15 changed files with 0 additions and 479 deletions
-
47backend_fastapi/auth.py
-
29backend_fastapi/database.py
-
26backend_fastapi/general.py
-
47backend_fastapi/models.py
-
3backend_fastapi/reports.py
-
106backend_fastapi/repositories.py
-
46backend_fastapi/schemas.py
-
23backend_fastapi/stored.py
-
46main.py
-
6requierements.txt
-
BINsrc/assets/cat-img.png
-
8src/js/my-comp.js
-
45src/style.css
-
47test.html
-
0test.py
@ -1,47 +0,0 @@ |
|||
from fastapi import APIRouter, BackgroundTasks |
|||
import backend_fastapi.schemas as schemas |
|||
from backend_fastapi.repositories import get_stored_roles, add_role, add_user, get_role_all, update_role, delete_role, update_user,delete_user,get_users |
|||
from typing import List |
|||
router = APIRouter() |
|||
|
|||
@router.post("/role") |
|||
async def create_role(role: schemas.RoleCreate) -> schemas.Role: |
|||
return await add_role(role) |
|||
|
|||
@router.get("/stored_role") |
|||
async def get_stored_role() -> List[schemas.Role]: |
|||
return await get_stored_roles() |
|||
|
|||
@router.get("/role") |
|||
async def get_role(limit:int=10, page:int=0) -> List[schemas.Role]: |
|||
return await get_role_all(limit, page) |
|||
|
|||
@router.patch("/role") |
|||
async def change_role(role: schemas.Role, id: int) -> None: |
|||
return await update_role(role, id) |
|||
|
|||
@router.delete("/role") |
|||
async def remove_role(id: int) -> schemas.Role: |
|||
return await delete_role(id) |
|||
|
|||
@router.post("/user") |
|||
async def create_user(user: schemas.UserCreate) -> schemas.User: |
|||
import hashlib |
|||
user.hashed_password = hashlib.sha256(user.hashed_password.encode('utf-8')).hexdigest() |
|||
return await add_user(user) |
|||
|
|||
|
|||
@router.get('/user') |
|||
async def show_users(limit:int=10, page:int=0): |
|||
return await get_users(limit, page) |
|||
|
|||
@router.patch('/user') |
|||
async def change_users(user: schemas.User, id: int): |
|||
import hashlib |
|||
if user.hashed_password: |
|||
user.hashed_password = hashlib.sha256(user.hashed_password.encode('utf-8')).hexdigest() |
|||
return await update_user(user, id) |
|||
|
|||
@router.delete('/user') |
|||
async def remove_users(id: int): |
|||
return await delete_user(id) |
@ -1,29 +0,0 @@ |
|||
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker |
|||
from sqlalchemy.orm import DeclarativeBase |
|||
import os |
|||
from dotenv import load_dotenv |
|||
load_dotenv() |
|||
class Model(DeclarativeBase): |
|||
pass |
|||
|
|||
async_engine = create_async_engine( |
|||
os.getenv("SQL_URL"), |
|||
connect_args={"check_same_thread": False} |
|||
) |
|||
|
|||
|
|||
async_session = async_sessionmaker( |
|||
async_engine, |
|||
autoflush=True, |
|||
autocommit=False, |
|||
expire_on_commit =False |
|||
) |
|||
|
|||
|
|||
async def connect() -> None: |
|||
async with async_engine.begin() as conn: |
|||
await conn.run_sync(Model.metadata.create_all, checkfirst=True) |
|||
|
|||
async def disconnect() -> None: |
|||
if async_engine: |
|||
await async_engine.dispose() |
@ -1,26 +0,0 @@ |
|||
from fastapi import APIRouter |
|||
import backend_fastapi.schemas as schemas |
|||
import backend_fastapi.repositories as repo |
|||
import asyncio |
|||
router = APIRouter() |
|||
|
|||
@router.get("/values") |
|||
async def get_values() -> list[schemas.Value]: |
|||
return await repo.get_values() |
|||
|
|||
|
|||
@router.get("/objects") |
|||
async def get_objects() -> list[schemas.Object]: |
|||
return await repo.get_objects() |
|||
|
|||
@router.get("/report") |
|||
async def get_report() -> None: |
|||
import pandas as pd |
|||
values, objects = await asyncio.gather(repo.get_values(), repo.get_objects()) |
|||
values = [schemas.Value.model_validate(value).model_dump() for value in values] |
|||
objects = [schemas.Object.model_validate(object).model_dump() for object in objects] |
|||
|
|||
df_values= pd.DataFrame(data=values) |
|||
df_objects= pd.DataFrame(data=objects) |
|||
df_type = df_values['id_param'].where(df_values['id_param'] == 3).notnull() |
|||
print(df_values[["id_object","value"]][df_type].set_index("id_object").join(df_objects[["id","id_city"]].set_index("id"),how='inner')) |
@ -1,47 +0,0 @@ |
|||
from .database import Model |
|||
from sqlalchemy.orm import mapped_column, Mapped, relationship |
|||
from sqlalchemy import String, Boolean, ForeignKey, Date |
|||
from sqlalchemy.dialects.mssql import SQL_VARIANT, UNIQUEIDENTIFIER |
|||
from uuid import UUID |
|||
from datetime import date |
|||
class Role(Model): |
|||
__tablename__ = "roles" |
|||
|
|||
id: Mapped[int] = mapped_column(primary_key=True) |
|||
name: Mapped[str] = mapped_column(String(255),nullable=False) |
|||
|
|||
class User(Model): |
|||
__tablename__ = "users" |
|||
|
|||
id: Mapped[int] = mapped_column( primary_key=True) |
|||
firstname: Mapped[str] = mapped_column(String(255),nullable=False) |
|||
lastname: Mapped[str] = mapped_column(String(255),nullable=False) |
|||
email: Mapped[str] = mapped_column(String(255),nullable=False) |
|||
hashed_password: Mapped[str] = mapped_column(String(255),nullable=False) |
|||
is_active: Mapped[bool] = mapped_column(Boolean,default=True) |
|||
role_id: Mapped[int] = mapped_column(ForeignKey("roles.id")) |
|||
role: Mapped["Role"] = relationship() |
|||
|
|||
|
|||
class Object(Model): |
|||
__tablename__ = "vObjects" |
|||
|
|||
id: Mapped[UUID] = mapped_column(UNIQUEIDENTIFIER, primary_key=True) |
|||
id_parent: Mapped[UUID|None] = mapped_column(UNIQUEIDENTIFIER,nullable=True) |
|||
year: Mapped[int | None] = mapped_column(nullable=False) |
|||
id_city: Mapped[int] = mapped_column(nullable=False) |
|||
|
|||
|
|||
class Value(Model): |
|||
__tablename__ = "vValues" |
|||
id: Mapped[int] = mapped_column( primary_key=True) |
|||
id_object: Mapped[UUID] = mapped_column(ForeignKey("vObjects.id")) |
|||
id_param:Mapped[int] = mapped_column(nullable=False) |
|||
value:Mapped[str|None] = mapped_column(String(250)) |
|||
date_s: Mapped[date] = mapped_column(Date,nullable=False) |
|||
date_po: Mapped[date|None] = mapped_column(Date,nullable=True) |
|||
id_user:Mapped[int] = mapped_column(nullable=False) |
|||
|
|||
|
|||
# class Parameter(Model): |
|||
# __tablename__ = "vParameters" |
@ -1,3 +0,0 @@ |
|||
import pandas as pd |
|||
import asyncio |
|||
|
@ -1,106 +0,0 @@ |
|||
from sqlalchemy import select, update, delete |
|||
from fastapi.exceptions import HTTPException |
|||
from backend_fastapi.stored import exec_procedure |
|||
import backend_fastapi.models as models |
|||
from .database import async_session |
|||
import backend_fastapi.schemas as schemas |
|||
|
|||
|
|||
async def add_role(role: schemas.RoleCreate): |
|||
async with async_session() as session: |
|||
model = models.Role(name = role.name) |
|||
session.add(model) |
|||
await session.flush() |
|||
await session.commit() |
|||
return model |
|||
|
|||
async def get_role_all(limit:int=10,page:int=0): |
|||
async with async_session() as session: |
|||
result = await session.scalars(select(models.Role).order_by(models.Role.id).limit(limit).offset(page*limit)) |
|||
return result.all() |
|||
|
|||
async def delete_role(id: int): |
|||
async with async_session() as session: |
|||
data = await session.scalars(select(models.Role).filter(models.Role.id == id)) |
|||
result = data.one_or_none() |
|||
if not result: |
|||
raise HTTPException(status_code=404, detail="Item not found") |
|||
await session.execute(delete(models.Role).filter(models.Role.id == id)) |
|||
await session.commit() |
|||
return result |
|||
|
|||
|
|||
async def update_role(role: schemas.Role, id: int): |
|||
async with async_session() as session: |
|||
data = await session.scalars(select(models.Role).filter(models.Role.id == id)) |
|||
result = data.one_or_none() |
|||
if not result: |
|||
raise HTTPException(status_code=404, detail="Item not found") |
|||
|
|||
query = update(models.Role).filter(models.Role.id == id).values(name = role.name) |
|||
await session.execute(query) |
|||
await session.commit() |
|||
return {f"{id=} был обновлен"} |
|||
|
|||
async def add_user(user: schemas.UserCreate): |
|||
async with async_session() as session: |
|||
model = models.User( |
|||
**user.model_dump() |
|||
) |
|||
session.add(model) |
|||
await session.flush() |
|||
await session.commit() |
|||
return model |
|||
|
|||
|
|||
async def get_users(limit:int=10,page:int=0): |
|||
async with async_session() as session: |
|||
result = await session.scalars(select(models.User).order_by(models.User.id).limit(limit).offset(page*limit)) |
|||
return result.all() |
|||
|
|||
async def delete_user(id: int): |
|||
async with async_session() as session: |
|||
data = await session.scalars(select(models.User).filter(models.User.id == id)) |
|||
result = data.one_or_none() |
|||
if not result: |
|||
raise HTTPException(status_code=404, detail="Item not found") |
|||
await session.execute(delete(models.User).filter(models.User.id == id)) |
|||
await session.commit() |
|||
return result |
|||
|
|||
|
|||
|
|||
async def update_user(user: schemas.User, id: int): |
|||
async with async_session() as session: |
|||
data = await session.scalars(select(models.User).filter(models.User.id == id)) |
|||
result = data.one_or_none() |
|||
if not result: |
|||
raise HTTPException(status_code=404, detail="Item not found") |
|||
query = update(models.User).filter(models.User.id == id)\ |
|||
.values( |
|||
firstname = user.firstname, |
|||
lastname = user.lastname, |
|||
email = user.email, |
|||
hashed_password= user.hashed_password, |
|||
is_active = user.is_active, |
|||
role_id = user.role_id, |
|||
) |
|||
await session.execute(query) |
|||
await session.commit() |
|||
return {f"{id=} был обновлен"} |
|||
|
|||
|
|||
async def get_objects(): |
|||
async with async_session() as session: |
|||
result = await session.scalars(select(models.Object)) |
|||
return result.all() |
|||
|
|||
|
|||
async def get_values(): |
|||
async with async_session() as session: |
|||
result = await session.scalars(select(models.Value)) |
|||
return result.all() |
|||
|
|||
|
|||
async def get_stored_roles(): |
|||
return await exec_procedure('get_roles') |
@ -1,46 +0,0 @@ |
|||
from pydantic import BaseModel, ConfigDict, EmailStr |
|||
from uuid import UUID |
|||
from datetime import date |
|||
class RoleBase(BaseModel): |
|||
name: str |
|||
|
|||
class UserBase(BaseModel): |
|||
firstname: str |
|||
lastname: str |
|||
email: EmailStr |
|||
hashed_password: str |
|||
role_id: int |
|||
is_active: bool = True |
|||
|
|||
class RoleCreate(RoleBase): |
|||
pass |
|||
|
|||
class UserCreate(UserBase): |
|||
pass |
|||
|
|||
class User(UserBase): |
|||
model_config = ConfigDict(from_attributes=True) |
|||
id: int |
|||
|
|||
class Role(RoleBase): |
|||
model_config = ConfigDict(from_attributes=True) |
|||
id: int |
|||
|
|||
|
|||
class Object(BaseModel): |
|||
model_config = ConfigDict(from_attributes=True) |
|||
id: UUID |
|||
id_city: int |
|||
id_parent: UUID | None |
|||
year: int | None |
|||
|
|||
|
|||
class Value(BaseModel): |
|||
model_config = ConfigDict(from_attributes=True) |
|||
id: int |
|||
id_object: UUID |
|||
id_param: int |
|||
value: str|None |
|||
date_s: date |
|||
date_po: date|None |
|||
id_user: int |
@ -1,23 +0,0 @@ |
|||
from sqlalchemy import text |
|||
from .database import async_session |
|||
|
|||
async def exec_procedure(proc_name, params:dict = None, database: str = None): |
|||
async with async_session() as session: |
|||
sql_params = "" |
|||
if params: |
|||
sql_params = ",".join([f"@{key} = :{key}" |
|||
for key, value in params.items()]) |
|||
dbstr = "" |
|||
if database: |
|||
dbstr = f"[{database}]." |
|||
sql_string = text(f''' |
|||
DECLARE @return_value int; |
|||
EXEC @return_value = {dbstr}[dbo].[{proc_name}] {sql_params}; |
|||
SELECT 'Return Value' = @return_value; |
|||
''') |
|||
datas = await session.execute( |
|||
sql_string, params) |
|||
await session.commit() |
|||
return [dict(data._mapping) for data in datas.fetchall()] |
|||
|
|||
|
@ -1,46 +0,0 @@ |
|||
from fastapi import FastAPI |
|||
from fastapi.responses import HTMLResponse |
|||
from fastapi.middleware.cors import CORSMiddleware |
|||
from contextlib import asynccontextmanager |
|||
from backend_fastapi.auth import router as auth_router |
|||
from backend_fastapi.general import router as general_router |
|||
from backend_fastapi.database import connect, disconnect |
|||
|
|||
@asynccontextmanager |
|||
async def lifespan(app: FastAPI): |
|||
await connect() |
|||
yield |
|||
await disconnect() |
|||
|
|||
|
|||
app = FastAPI(lifespan=lifespan) |
|||
origins = [ |
|||
"http://localhost", |
|||
"http://localhost:8000", |
|||
"http://localhost:3000", |
|||
"http://localhost:5173" |
|||
] |
|||
|
|||
app.add_middleware( |
|||
CORSMiddleware, |
|||
allow_origins=origins, |
|||
allow_credentials=True, |
|||
allow_methods=["*"], |
|||
allow_headers=["*"], |
|||
) |
|||
|
|||
@app.get("/") |
|||
def index(): |
|||
html_content = "<h2>Hello METANIT.COM!</h2>" |
|||
return HTMLResponse(content=html_content) |
|||
|
|||
@app.get("/cat") |
|||
async def get_data(): |
|||
return {"firstname": "Котофей","lastname":"Барсикофф","age":"10"} |
|||
|
|||
app.include_router(router=auth_router, prefix="/auth", tags=["Auth"]) |
|||
app.include_router(router=general_router, prefix="/general", tags=["General"]) |
|||
|
|||
if __name__ == "__main__": |
|||
import uvicorn |
|||
uvicorn.run(app, host="0.0.0.0", port=8000) |
@ -1,6 +0,0 @@ |
|||
uvicorn |
|||
fastapi |
|||
sqlalchemy |
|||
aioodbc |
|||
python-dotenv |
|||
pandas |
Before Width: 1680 | Height: 1839 | Size: 1.4 MiB |
@ -1,8 +0,0 @@ |
|||
import { ref } from 'vue' |
|||
export default { |
|||
setup() { |
|||
const count = ref(0) |
|||
return { count } |
|||
}, |
|||
template: `<div>Count is: {{ count }}</div>` |
|||
} |
@ -1,45 +0,0 @@ |
|||
|
|||
.card{ |
|||
width: 250px; |
|||
height: 350px; |
|||
border:1px solid black; |
|||
border-radius: 5px; |
|||
align-items: center; |
|||
} |
|||
|
|||
.card-img { |
|||
height: 250px; |
|||
width: 250px; |
|||
position: relative; |
|||
} |
|||
img { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
.card-fullname { |
|||
width: 100%; |
|||
height: 50px; |
|||
align-items: center; |
|||
display: inline-flex; |
|||
} |
|||
.card-fullname div { |
|||
font-size: larger; |
|||
font-weight:bold; |
|||
width: 100%; |
|||
text-align: center; |
|||
} |
|||
|
|||
.card-age { |
|||
align-items: center; |
|||
width: 100%; |
|||
display: flex; |
|||
position: relative; |
|||
} |
|||
|
|||
.card-age span { |
|||
width: 100%; |
|||
text-align: center; |
|||
font-size: small; |
|||
font-weight: 100; |
|||
} |
@ -1,47 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="ru"> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<title>Document</title> |
|||
<link href="/src/style.css" rel="stylesheet"/> |
|||
</head> |
|||
<body> |
|||
<script type="importmap"> |
|||
{ |
|||
"imports": { |
|||
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
|
|||
<div id="app"> |
|||
<div class="card"> |
|||
<div class="card-img"> |
|||
<img src="/src/assets/cat-img.png"/> |
|||
</div> |
|||
<div class="card-fullname"> |
|||
<div>{{cat_data.firstname}} {{cat_data.lastname}}</div> |
|||
</div> |
|||
<div class="card-age"> |
|||
<span>{{cat_data.age}}</span> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
<script type="module"> |
|||
import { createApp, ref } from 'vue' |
|||
createApp({ |
|||
setup() { |
|||
const cat_data = ref(null); |
|||
fetch("http://localhost:8000/cat").then( res => res.json()).then(data => cat_data.value = data); |
|||
return { |
|||
cat_data |
|||
} |
|||
} |
|||
}).mount('#app') |
|||
</script> |
|||
|
|||
</body> |
|||
</html> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue