5 Commits

42 changed files with 705 additions and 423 deletions

View File

@@ -1,15 +1,15 @@
import sys
import logging import logging
import sys
import loguru import loguru
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from uvicorn import run from uvicorn import run
from api.config import get_settings, DefaultSettings from api.config import DefaultSettings, get_settings
from api.endpoints import list_of_routes from api.endpoints import list_of_routes
from api.utils.common import get_hostname
from api.services.middleware import MiddlewareAccessTokenValidadtion from api.services.middleware import MiddlewareAccessTokenValidadtion
from api.utils.common import get_hostname
logger = logging.getLogger() logger = logging.getLogger()
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
@@ -52,7 +52,6 @@ prod_origins = [""]
origins = dev_origins if get_settings().ENV == "local" else prod_origins origins = dev_origins if get_settings().ENV == "local" else prod_origins
if __name__ == "__main__": if __name__ == "__main__":
settings_for_application = get_settings() settings_for_application = get_settings()
if settings_for_application.ENV == "prod": if settings_for_application.ENV == "prod":

View File

@@ -7,7 +7,7 @@ from sqlalchemy import pool
from alembic import context from alembic import context
from api.db import metadata, tables from orm import metadata, tables
# this is the Alembic Config object, which provides # this is the Alembic Config object, which provides
# access to the values within the .ini file in use. # access to the values within the .ini file in use.

View File

@@ -0,0 +1,38 @@
"""empty message
Revision ID: 816be8c60ab4
Revises: 93106fbe7d83
Create Date: 2025-09-12 14:48:47.726269
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision: str = '816be8c60ab4'
down_revision: Union[str, None] = '93106fbe7d83'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('ps_node', 'node_type',
existing_type=mysql.ENUM('TYPE1', 'TYPE2', 'TYPE3'),
type_=sa.Enum('LISTEN', 'IF', 'START', name='nodetype'),
existing_nullable=False)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('ps_node', 'node_type',
existing_type=sa.Enum('LISTEN', 'IF', 'START', name='nodetype'),
type_=mysql.ENUM('TYPE1', 'TYPE2', 'TYPE3'),
existing_nullable=False)
# ### end Alembic commands ###

View File

@@ -0,0 +1,32 @@
"""update node_link_table link_point_id default
Revision ID: cc3b95f1f99d
Revises: 816be8c60ab4
Create Date: 2025-09-12 19:17:03.125276
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision: str = 'cc3b95f1f99d'
down_revision: Union[str, None] = '816be8c60ab4'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('node_link', sa.Column('link_point_id', sa.Integer().with_variant(mysql.INTEGER(unsigned=True), 'mysql'), nullable=False))
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('node_link', 'link_point_id')
# ### end Alembic commands ###

View File

@@ -6,7 +6,7 @@ from typing import Optional
from sqlalchemy import insert, select, func, or_, and_, asc, desc from sqlalchemy import insert, select, func, or_, and_, asc, desc
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.tables.account import account_table from orm.tables.account import account_table
from api.schemas.account.account import User from api.schemas.account.account import User
from api.schemas.endpoints.account import all_user_adapter, AllUser, AllUserResponse, UserCreate, UserFilterDTO from api.schemas.endpoints.account import all_user_adapter, AllUser, AllUserResponse, UserCreate, UserFilterDTO

View File

@@ -4,7 +4,7 @@ from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from enum import Enum from enum import Enum
from api.db.tables.account import account_table, account_keyring_table, KeyType, KeyStatus from orm.tables.account import account_table, account_keyring_table, KeyType, KeyStatus
from api.schemas.account.account import User from api.schemas.account.account import User
from api.schemas.account.account_keyring import AccountKeyring from api.schemas.account.account_keyring import AccountKeyring

View File

@@ -6,7 +6,7 @@ from sqlalchemy import insert, select, update
from sqlalchemy.dialects.mysql import insert as mysql_insert from sqlalchemy.dialects.mysql import insert as mysql_insert
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.tables.account import account_keyring_table, KeyStatus, KeyType from orm.tables.account import account_keyring_table, KeyStatus, KeyType
from api.schemas.account.account_keyring import AccountKeyring from api.schemas.account.account_keyring import AccountKeyring
from api.utils.hasher import hasher from api.utils.hasher import hasher

View File

@@ -7,7 +7,7 @@ from datetime import datetime, timezone
from sqlalchemy import insert, select, func, or_, and_, asc, desc from sqlalchemy import insert, select, func, or_, and_, asc, desc
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.tables.events import list_events_table from orm.tables.events import list_events_table
from api.schemas.events.list_events import ListEvent from api.schemas.events.list_events import ListEvent

View File

@@ -0,0 +1,78 @@
from typing import Optional
from datetime import datetime, timezone
from sqlalchemy import insert, select, desc
from sqlalchemy.ext.asyncio import AsyncConnection
from api.schemas.process.node_link import NodeLink
from orm.tables.process import ps_node_table, node_link_table
from orm.tables.process import NodeLinkStatus
async def get_last_link_name_by_node_id(
connection: AsyncConnection, ps_id: int
) -> Optional[str]:
"""
Получает link_name из последней записи node_link по ps_id.
Находит все node_id в ps_node по ps_id, затем ищет связи в node_link
и возвращает link_name из самой последней записи.
"""
query = select(node_link_table.c.link_name).where(
node_link_table.c.node_id.in_(
select(ps_node_table.c.id).where(ps_node_table.c.ps_id == ps_id)
)
).order_by(desc(node_link_table.c.created_at)).limit(1)
result = await connection.execute(query)
link_name = result.scalar_one_or_none()
return link_name
async def get_last_node_link_by_creator_and_ps_id(
connection: AsyncConnection, creator_id: int, node_link_id: int
) -> Optional[NodeLink]:
"""
Получает последнюю созданную node_link для данного создателя и процесса.
"""
query = select(node_link_table).where(
node_link_table.c.creator_id == creator_id,
node_link_table.c.node_id.in_(
select(ps_node_table.c.id).where(ps_node_table.c.id == node_link_id)
)
).order_by(desc(node_link_table.c.created_at)).limit(1)
node_link_db_cursor = await connection.execute(query)
node_link_data = node_link_db_cursor.mappings().one_or_none()
if not node_link_data:
return None
return NodeLink.model_validate(node_link_data)
async def create_node_link_schema(
connection: AsyncConnection, validated_link_schema, creator_id: int,
) -> Optional[NodeLink]:
"""
Создает нове поле в таблице process_schema_table.
"""
query = insert(node_link_table).values(
link_name=validated_link_schema.link_name,
node_id=validated_link_schema.from_id,
link_point_id=validated_link_schema.parent_port_number,
next_node_id=validated_link_schema.to_id,
settings={},
creator_id=creator_id,
created_at=datetime.now(timezone.utc),
status=NodeLinkStatus.ACTIVE.value,
)
await connection.execute(query)
await connection.commit()
return await get_last_node_link_by_creator_and_ps_id(connection, creator_id, validated_link_schema.from_id)

View File

@@ -1,4 +1,4 @@
from typing import Optional from typing import Optional, Dict, Any
import math import math
from datetime import datetime, timezone from datetime import datetime, timezone
@@ -6,7 +6,7 @@ from datetime import datetime, timezone
from sqlalchemy import insert, select, func, or_, and_, asc, desc from sqlalchemy import insert, select, func, or_, and_, asc, desc
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.tables.process import process_schema_table from orm.tables.process import process_schema_table
from api.schemas.process.process_schema import ProcessSchema from api.schemas.process.process_schema import ProcessSchema
@@ -152,6 +152,42 @@ async def update_process_schema_by_id(connection: AsyncConnection, update_values
await connection.commit() await connection.commit()
async def update_process_schema_settings_by_id(
connection: AsyncConnection,
process_schema_id: int,
node_data: Dict[str, Any]
):
"""
Добавляет новый узел в массив 'nodes' в настройках процесса.
Если массив 'nodes' не существует, создает его.
"""
# Получаем текущие settings
query = select(process_schema_table.c.settings).where(process_schema_table.c.id == process_schema_id)
result = await connection.execute(query)
current_settings = result.scalar_one_or_none()
# Если settings пустые, создаем пустой словарь
if current_settings is None:
current_settings = {}
# Инициализируем массив nodes, если его нет
if "nodes" not in current_settings:
current_settings["nodes"] = []
# Добавляем новый узел в массив
current_settings["nodes"].append(node_data)
# Обновляем поле settings
await connection.execute(
process_schema_table.update()
.where(process_schema_table.c.id == process_schema_id)
.values(settings=current_settings)
)
await connection.commit()
async def create_process_schema( async def create_process_schema(
connection: AsyncConnection, process_schema: ProcessSchema, creator_id: int connection: AsyncConnection, process_schema: ProcessSchema, creator_id: int
) -> Optional[ProcessSchema]: ) -> Optional[ProcessSchema]:

106
api/api/db/logic/ps_node.py Normal file
View File

@@ -0,0 +1,106 @@
from typing import Optional
from datetime import datetime, timezone
from sqlalchemy import insert, select, desc
from sqlalchemy.ext.asyncio import AsyncConnection
from orm.tables.process import ps_node_table
from api.schemas.process.ps_node import Ps_Node
from model_nodes.node_start_models import StartNodeCoreSchema
from orm.tables.process import NodeStatus,NodeType
async def get_ps_node_by_id(connection: AsyncConnection, id: int) -> Optional[Ps_Node]:
"""
Получает process_schema по id.
"""
query = select(ps_node_table).where(ps_node_table.c.id == id)
ps_node_db_cursor = await connection.execute(query)
ps_node_data = ps_node_db_cursor.mappings().one_or_none()
if not ps_node_data:
return None
return Ps_Node.model_validate(ps_node_data)
async def get_ps_node_by_type_and_ps_id(connection: AsyncConnection, node_type: str, ps_id: int) -> Optional[Ps_Node]:
"""
Получает ps_node по node_type и ps_id.
"""
query = select(ps_node_table).where(
ps_node_table.c.node_type == node_type,
ps_node_table.c.ps_id == ps_id
)
ps_node_db_cursor = await connection.execute(query)
ps_node_data = ps_node_db_cursor.mappings().one_or_none()
if not ps_node_data:
return None
return Ps_Node.model_validate(ps_node_data)
async def create_ps_node_start_schema(
connection: AsyncConnection, validated_start_schema: StartNodeCoreSchema, creator_id: int
) -> Optional[Ps_Node]:
"""
Создает нове поле в таблице process_schema_table.
"""
query = insert(ps_node_table).values(
ps_id=validated_start_schema.ps_id,
node_type=NodeType.START.value,
settings=validated_start_schema.data.model_dump(),
creator_id=creator_id,
created_at=datetime.now(timezone.utc),
status=NodeStatus.ACTIVE.value,
)
await connection.execute(query)
await connection.commit()
# return validated_start_schema
async def get_last_ps_node_by_creator_and_ps_id(
connection: AsyncConnection, creator_id: int, ps_id: int
) -> Optional[Ps_Node]:
"""
Получает последнюю созданную ps_node для данного создателя и процесса.
"""
query = select(ps_node_table).where(
ps_node_table.c.creator_id == creator_id,
ps_node_table.c.ps_id == ps_id
).order_by(desc(ps_node_table.c.created_at)).limit(1)
ps_node_db_cursor = await connection.execute(query)
ps_node_data = ps_node_db_cursor.mappings().one_or_none()
if not ps_node_data:
return None
return Ps_Node.model_validate(ps_node_data)
async def create_ps_node_schema(
connection: AsyncConnection, validated_schema, creator_id: int,
) -> Optional[Ps_Node]:
"""
Создает нове поле в таблице process_schema_table.
"""
query = insert(ps_node_table).values(
ps_id=validated_schema.ps_id,
node_type=validated_schema.node_type,
settings=validated_schema.data.model_dump(),
creator_id=creator_id,
created_at=datetime.now(timezone.utc),
status=NodeStatus.ACTIVE.value,
)
await connection.execute(query)
await connection.commit()
return await get_last_ps_node_by_creator_and_ps_id(connection, creator_id, validated_schema.ps_id)

View File

@@ -1,18 +0,0 @@
__all__ = ["BigIntegerPK", "SAEnum", "UnsignedInt"]
from typing import Any
from sqlalchemy import BigInteger, Enum, Integer
from sqlalchemy.dialects import mysql
# class SAEnum(Enum):
# def __init__(self, *enums: object, **kw: Any):
# validate_strings = kw.pop("validate_strings", True)
# super().__init__(*enums, **kw, validate_strings=validate_strings)
# # https://docs.sqlalchemy.org/en/20/dialects/sqlite.html#allowing-autoincrement-behavior-sqlalchemy-types-other-than-integer-integer
# BigIntegerPK = BigInteger().with_variant(Integer, "sqlite")
UnsignedInt = Integer().with_variant(mysql.INTEGER(unsigned=True), "mysql")

View File

@@ -1 +0,0 @@
from . import account, events, process

View File

@@ -1,65 +0,0 @@
import enum
from sqlalchemy import Table, Column, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index
from sqlalchemy.sql import func
from api.db.sql_types import UnsignedInt
from api.db import metadata
class AccountRole(enum.StrEnum):
OWNER = "OWNER"
ADMIN = "ADMIN"
EDITOR = "EDITOR"
VIEWER = "VIEWER"
class AccountStatus(enum.StrEnum):
ACTIVE = "ACTIVE"
DISABLED = "DISABLED"
BLOCKED = "BLOCKED"
DELETED = "DELETED"
account_table = Table(
"account",
metadata,
Column("id", UnsignedInt, primary_key=True, autoincrement=True),
Column("name", String(100), nullable=False),
Column("login", String(100), nullable=False),
Column("email", String(100), nullable=True),
Column("bind_tenant_id", String(40), nullable=True),
Column("role", SQLAEnum(AccountRole), nullable=False),
Column("meta", JSON, default={}),
Column("creator_id", UnsignedInt, ForeignKey("account.id"), nullable=True),
Column("created_at", DateTime(timezone=True), server_default=func.now()),
Column("status", SQLAEnum(AccountStatus), nullable=False),
Index("idx_login", "login"),
Index("idx_name", "name"),
)
class KeyType(enum.StrEnum):
PASSWORD = "PASSWORD"
ACCESS_TOKEN = "ACCESS_TOKEN"
REFRESH_TOKEN = "REFRESH_TOKEN"
API_KEY = "API_KEY"
class KeyStatus(enum.StrEnum):
ACTIVE = "ACTIVE"
EXPIRED = "EXPIRED"
DELETED = "DELETED"
account_keyring_table = Table(
"account_keyring",
metadata,
Column("owner_id", UnsignedInt, ForeignKey("account.id"), primary_key=True, nullable=False),
Column("key_type", SQLAEnum(KeyType), primary_key=True, nullable=False),
Column("key_id", String(40), primary_key=True, default=None),
Column("key_value", String(512), nullable=False),
Column("created_at", DateTime(timezone=True), server_default=func.now()),
Column("expiry", DateTime(timezone=True), nullable=True),
Column("status", SQLAEnum(KeyStatus), nullable=False),
)

View File

@@ -1,33 +0,0 @@
import enum
from sqlalchemy import Table, Column, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime
from sqlalchemy.sql import func
from api.db.sql_types import UnsignedInt
from api.db import metadata
class EventState(enum.StrEnum):
AUTO = "AUTO"
DESCRIPTED = "DESCRIPTED"
class EventStatus(enum.StrEnum):
ACTIVE = "ACTIVE"
DISABLED = "DISABLED"
DELETED = "DELETED"
list_events_table = Table(
"list_events",
metadata,
Column("id", UnsignedInt, primary_key=True, autoincrement=True),
Column("name", String(40, collation="latin1_bin"), nullable=False, unique=True),
Column("title", String(64), nullable=False),
Column("creator_id", UnsignedInt, ForeignKey("account.id"), nullable=False),
Column("created_at", DateTime(timezone=True), server_default=func.now()),
Column("schema", JSON, default={}),
Column("state", SQLAEnum(EventState), nullable=False),
Column("status", SQLAEnum(EventStatus), nullable=False),
)

View File

@@ -1,107 +0,0 @@
import enum
from sqlalchemy import (
Table,
Column,
String,
Text,
Enum as SQLAEnum,
JSON,
ForeignKey,
DateTime,
Index,
PrimaryKeyConstraint,
)
from sqlalchemy.sql import func
from enum import Enum
from api.db.sql_types import UnsignedInt
from api.db import metadata
class ProcessStatus(enum.StrEnum):
ACTIVE = "ACTIVE"
STOPPING = "STOPPING"
STOPPED = "STOPPED"
DELETED = "DELETED"
process_schema_table = Table(
"process_schema",
metadata,
Column("id", UnsignedInt, primary_key=True, autoincrement=True),
Column("title", String(100), nullable=False),
Column("description", Text, nullable=False),
Column("owner_id", UnsignedInt, ForeignKey("account.id"), nullable=False),
Column("creator_id", UnsignedInt, ForeignKey("account.id"), nullable=False),
Column("created_at", DateTime(timezone=True), server_default=func.now()),
Column("settings", JSON, default={}),
Column("status", SQLAEnum(ProcessStatus), nullable=False),
Index(
"idx_owner_id",
"owner_id",
),
)
process_version_archive_table = Table(
"process_version_archive",
metadata,
Column("id", UnsignedInt, autoincrement=True, nullable=False),
Column("ps_id", UnsignedInt, ForeignKey("process_schema.id"), nullable=False),
Column("version", UnsignedInt, default=1, nullable=False),
Column("snapshot", JSON, default={}),
Column("owner_id", UnsignedInt, ForeignKey("account.id"), nullable=False),
Column("created_at", DateTime(timezone=True), server_default=func.now()),
Column("is_last", UnsignedInt, default=0),
PrimaryKeyConstraint("id", "version"),
)
class NodeStatus(enum.StrEnum):
ACTIVE = "ACTIVE"
DISABLED = "DISABLED"
DELETED = "DELETED"
class NodeType(Enum):
TYPE1 = "Type1"
TYPE2 = "Type2"
TYPE3 = "Type3"
ps_node_table = Table(
"ps_node",
metadata,
Column("id", UnsignedInt, autoincrement=True, primary_key=True, nullable=False),
Column("ps_id", UnsignedInt, ForeignKey("process_schema.id"), nullable=False),
Column("node_type", SQLAEnum(NodeType), nullable=False),
Column("settings", JSON, default={}),
Column("creator_id", UnsignedInt, ForeignKey("account.id"), nullable=False),
Column("created_at", DateTime(timezone=True), server_default=func.now()),
Column("status", SQLAEnum(NodeStatus), nullable=False),
Index("idx_ps_id", "ps_id"),
)
class NodeLinkStatus(enum.StrEnum):
ACTIVE = "ACTIVE"
STOPPING = "STOPPING"
STOPPED = "STOPPED"
DELETED = "DELETED"
node_link_table = Table(
"node_link",
metadata,
Column("id", UnsignedInt, autoincrement=True, primary_key=True, nullable=False),
Column("link_name", String(20), nullable=False),
Column("node_id", UnsignedInt, ForeignKey("ps_node.id"), nullable=False),
Column("next_node_id", UnsignedInt, ForeignKey("ps_node.id"), nullable=False),
Column("settings", JSON, default={}),
Column("creator_id", UnsignedInt, ForeignKey("account.id"), nullable=False),
Column("created_at", DateTime(timezone=True), server_default=func.now()),
Column("status", SQLAEnum(NodeLinkStatus), nullable=False),
Index("idx_node_id", "node_id"),
Index("idx_next_node_id", "next_node_id"),
)

View File

@@ -4,8 +4,9 @@ from api.endpoints.account import api_router as account_router
from api.endpoints.keyring import api_router as keyring_router from api.endpoints.keyring import api_router as keyring_router
from api.endpoints.list_events import api_router as listevents_router from api.endpoints.list_events import api_router as listevents_router
from api.endpoints.process_schema import api_router as processschema_router from api.endpoints.process_schema import api_router as processschema_router
from api.endpoints.ps_node import api_router as ps_node_router
list_of_routes = [auth_router, profile_router, account_router, keyring_router, listevents_router, processschema_router] list_of_routes = [auth_router, profile_router, account_router, keyring_router, listevents_router, processschema_router, ps_node_router]
__all__ = [ __all__ = [
"list_of_routes", "list_of_routes",

View File

@@ -1,6 +1,7 @@
from fastapi import APIRouter, Depends, HTTPException, status, Query from typing import List, Optional
from typing import Optional, List from fastapi import APIRouter, Depends, HTTPException, Query, status
from orm.tables.account import AccountStatus
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.connection.session import get_connection_dep from api.db.connection.session import get_connection_dep
@@ -12,10 +13,9 @@ from api.db.logic.account import (
update_user_by_id, update_user_by_id,
) )
from api.db.logic.keyring import create_password_key, update_password_key from api.db.logic.keyring import create_password_key, update_password_key
from api.db.tables.account import AccountStatus
from api.schemas.account.account import User from api.schemas.account.account import User
from api.schemas.base import bearer_schema from api.schemas.base import bearer_schema
from api.schemas.endpoints.account import AllUserResponse, UserCreate, UserUpdate, UserFilterDTO from api.schemas.endpoints.account import AllUserResponse, UserCreate, UserFilterDTO, UserUpdate
from api.services.auth import get_current_user from api.services.auth import get_current_user
from api.services.user_role_validation import db_user_role_validation from api.services.user_role_validation import db_user_role_validation
@@ -26,7 +26,7 @@ api_router = APIRouter(
@api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllUserResponse) @api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllUserResponse)
async def get_all_account( async def get_all_account_endpoint(
page: int = Query(1, description="Page number", gt=0), page: int = Query(1, description="Page number", gt=0),
limit: int = Query(10, description="КNumber of items per page", gt=0), limit: int = Query(10, description="КNumber of items per page", gt=0),
search: Optional[str] = Query(None, description="Search term to filter by name or login or email"), search: Optional[str] = Query(None, description="Search term to filter by name or login or email"),
@@ -62,7 +62,7 @@ async def get_all_account(
@api_router.get("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=User) @api_router.get("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=User)
async def get_account( async def get_account_endpoint(
user_id: int, user_id: int,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),
@@ -78,7 +78,7 @@ async def get_account(
@api_router.post("", dependencies=[Depends(bearer_schema)], response_model=User) @api_router.post("", dependencies=[Depends(bearer_schema)], response_model=User)
async def create_account( async def create_account_endpoint(
user: UserCreate, user: UserCreate,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),
@@ -98,7 +98,7 @@ async def create_account(
@api_router.put("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=UserUpdate) @api_router.put("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=UserUpdate)
async def update_account( async def update_account_endpoint(
user_id: int, user_id: int,
user_update: UserUpdate, user_update: UserUpdate,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
@@ -126,7 +126,7 @@ async def update_account(
@api_router.delete("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=User) @api_router.delete("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=User)
async def delete_account( async def delete_account_endpoint(
user_id: int, user_id: int,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),

View File

@@ -49,7 +49,7 @@ def get_config():
@api_router.post("", response_model=Tokens) @api_router.post("", response_model=Tokens)
async def login_for_access_token( async def login_for_access_token_endpoint(
user: Auth, user: Auth,
response: Response, response: Response,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
@@ -84,7 +84,7 @@ async def login_for_access_token(
@api_router.post("/refresh", response_model=Tokens) @api_router.post("/refresh", response_model=Tokens)
async def refresh( async def refresh_endpoint(
request: Request, request: Request,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
Authorize: AuthJWT = Depends(), Authorize: AuthJWT = Depends(),

View File

@@ -1,31 +1,20 @@
from fastapi import ( from fastapi import (
APIRouter, APIRouter,
Body,
Depends, Depends,
Form,
HTTPException, HTTPException,
Response,
status, status,
) )
from orm.tables.account import KeyStatus
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.connection.session import get_connection_dep from api.db.connection.session import get_connection_dep
from api.db.logic.keyring import create_key, get_key_by_id, update_key_by_id
from api.db.logic.keyring import get_key_by_id, create_key, update_key_by_id from api.schemas.account.account_keyring import AccountKeyring
from api.db.tables.account import KeyStatus
from api.schemas.base import bearer_schema from api.schemas.base import bearer_schema
from api.schemas.endpoints.account_keyring import AccountKeyringUpdate from api.schemas.endpoints.account_keyring import AccountKeyringUpdate
from api.schemas.account.account_keyring import AccountKeyring
from api.services.auth import get_current_user from api.services.auth import get_current_user
from api.services.user_role_validation import db_user_role_validation from api.services.user_role_validation import db_user_role_validation
api_router = APIRouter( api_router = APIRouter(
prefix="/keyring", prefix="/keyring",
tags=["User KeyringModel"], tags=["User KeyringModel"],
@@ -33,7 +22,7 @@ api_router = APIRouter(
@api_router.get("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring) @api_router.get("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring)
async def get_keyring( async def get_keyring_endpoint (
key_id: str, connection: AsyncConnection = Depends(get_connection_dep), current_user=Depends(get_current_user) key_id: str, connection: AsyncConnection = Depends(get_connection_dep), current_user=Depends(get_current_user)
): ):
authorize_user = await db_user_role_validation(connection, current_user) authorize_user = await db_user_role_validation(connection, current_user)
@@ -47,7 +36,7 @@ async def get_keyring(
@api_router.post("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring) @api_router.post("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring)
async def create_keyring( async def create_keyring_endpoint(
user_id: int, user_id: int,
key_id: str, key_id: str,
key: AccountKeyringUpdate, key: AccountKeyringUpdate,
@@ -73,7 +62,7 @@ async def create_keyring(
@api_router.put("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring) @api_router.put("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring)
async def update_keyring( async def update_keyring_endpoint(
user_id: int, user_id: int,
key_id: str, key_id: str,
keyring_update: AccountKeyringUpdate, keyring_update: AccountKeyringUpdate,
@@ -99,7 +88,7 @@ async def update_keyring(
@api_router.delete("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring) @api_router.delete("/{user_id}/{key_id}", dependencies=[Depends(bearer_schema)], response_model=AccountKeyring)
async def delete_keyring( async def delete_keyring_endpoint(
user_id: int, user_id: int,
key_id: str, key_id: str,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),

View File

@@ -1,37 +1,27 @@
from fastapi import APIRouter, Depends, HTTPException, status, Query from typing import List, Optional
from typing import Optional, List
from fastapi import APIRouter, Depends, HTTPException, Query, status
from orm.tables.events import EventStatus
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.connection.session import get_connection_dep from api.db.connection.session import get_connection_dep
from api.db.logic.account import get_user_by_login from api.db.logic.account import get_user_by_login
from api.db.logic.list_events import ( from api.db.logic.list_events import (
get_list_events_by_name,
get_list_events_by_id,
create_list_events, create_list_events,
update_list_events_by_id, get_list_events_by_id,
get_list_events_by_name,
get_list_events_page_DTO, get_list_events_page_DTO,
update_list_events_by_id,
) )
from api.schemas.events.list_events import ListEvent
from api.db.tables.events import EventStatus
from api.schemas.base import bearer_schema from api.schemas.base import bearer_schema
from api.schemas.endpoints.list_events import AllListEventResponse, ListEventFilterDTO, ListEventUpdate
from api.schemas.endpoints.list_events import ListEventUpdate, AllListEventResponse, ListEventFilterDTO from api.schemas.events.list_events import ListEvent
from api.services.auth import get_current_user from api.services.auth import get_current_user
from api.services.user_role_validation import ( from api.services.user_role_validation import (
db_user_role_validation_for_list_events_and_process_schema_by_list_event_id,
db_user_role_validation_for_list_events_and_process_schema, db_user_role_validation_for_list_events_and_process_schema,
db_user_role_validation_for_list_events_and_process_schema_by_list_event_id,
) )
api_router = APIRouter( api_router = APIRouter(
prefix="/list_events", prefix="/list_events",
tags=["list events"], tags=["list events"],
@@ -39,7 +29,7 @@ api_router = APIRouter(
@api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllListEventResponse) @api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllListEventResponse)
async def get_all_list_events( async def get_all_list_events_endpoint(
page: int = Query(1, description="Page number", gt=0), page: int = Query(1, description="Page number", gt=0),
limit: int = Query(10, description="Number of items per page", gt=0), limit: int = Query(10, description="Number of items per page", gt=0),
search: Optional[str] = Query(None, description="Search term to filter by title or name"), search: Optional[str] = Query(None, description="Search term to filter by title or name"),
@@ -82,7 +72,7 @@ async def get_all_list_events(
@api_router.get("/{list_events_id}", dependencies=[Depends(bearer_schema)], response_model=ListEvent) @api_router.get("/{list_events_id}", dependencies=[Depends(bearer_schema)], response_model=ListEvent)
async def get_list_events( async def get_list_events_endpoint(
list_events_id: int, list_events_id: int,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),
@@ -103,7 +93,7 @@ async def get_list_events(
@api_router.post("", dependencies=[Depends(bearer_schema)], response_model=ListEvent) @api_router.post("", dependencies=[Depends(bearer_schema)], response_model=ListEvent)
async def create_list_events( async def create_list_events_endpoint(
list_events: ListEventUpdate, list_events: ListEventUpdate,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),
@@ -151,7 +141,7 @@ async def update_list_events(
@api_router.delete("/{list_events_id}", dependencies=[Depends(bearer_schema)], response_model=ListEvent) @api_router.delete("/{list_events_id}", dependencies=[Depends(bearer_schema)], response_model=ListEvent)
async def delete_list_events( async def delete_list_events_endpoint(
list_events_id: int, list_events_id: int,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),

View File

@@ -1,35 +1,40 @@
from fastapi import APIRouter, Depends, HTTPException, status, Query from typing import List, Optional
from typing import Optional, List from fastapi import APIRouter, Depends, HTTPException, Query, status
from orm.tables.process import ProcessStatus
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.connection.session import get_connection_dep from api.db.connection.session import get_connection_dep
from api.db.logic.account import get_user_by_login from api.db.logic.account import get_user_by_login
from api.db.logic.process_schema import ( from api.db.logic.process_schema import (
get_process_schema_by_title,
create_process_schema, create_process_schema,
get_process_schema_by_id, get_process_schema_by_id,
update_process_schema_by_id, get_process_schema_by_title,
get_process_schema_page_DTO, get_process_schema_page_DTO,
update_process_schema_by_id,
) )
from api.schemas.process.process_schema import ProcessSchema
from api.db.tables.process import ProcessStatus
from api.schemas.base import bearer_schema from api.schemas.base import bearer_schema
from api.schemas.endpoints.process_schema import AllProcessSchemaResponse, ProcessSchemaFilterDTO, ProcessSchemaUpdate
from api.schemas.endpoints.process_schema import ProcessSchemaUpdate, AllProcessSchemaResponse, ProcessSchemaFilterDTO from api.schemas.process.process_schema import ProcessSchema, ProcessSchemaSettingsNode, ProcessSchemaResponse
from api.schemas.process.ps_node import Ps_NodeFrontResponseNode
from api.schemas.process.ps_node import Ps_NodeFrontResponse
from api.services.auth import get_current_user from api.services.auth import get_current_user
from api.services.user_role_validation import ( from api.services.user_role_validation import (
db_user_role_validation_for_list_events_and_process_schema_by_list_event_id,
db_user_role_validation_for_list_events_and_process_schema, db_user_role_validation_for_list_events_and_process_schema,
db_user_role_validation_for_list_events_and_process_schema_by_list_event_id,
) )
from core import VorkNodeStart
from model_nodes import StartNodeData
from api.db.logic.ps_node import create_ps_node_schema
from api.db.logic.process_schema import update_process_schema_settings_by_id
from orm.tables.process import NodeType
api_router = APIRouter( api_router = APIRouter(
prefix="/process_schema", prefix="/process_schema",
@@ -38,7 +43,7 @@ api_router = APIRouter(
@api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllProcessSchemaResponse) @api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllProcessSchemaResponse)
async def get_all_process_schema( async def get_all_process_schema_endpoint(
page: int = Query(1, description="Page number", gt=0), page: int = Query(1, description="Page number", gt=0),
limit: int = Query(10, description="Number of items per page", gt=0), limit: int = Query(10, description="Number of items per page", gt=0),
search: Optional[str] = Query(None, description="Search term to filter by title or description"), search: Optional[str] = Query(None, description="Search term to filter by title or description"),
@@ -81,7 +86,7 @@ async def get_all_process_schema(
@api_router.get("/{process_schema_id}", dependencies=[Depends(bearer_schema)], response_model=ProcessSchema) @api_router.get("/{process_schema_id}", dependencies=[Depends(bearer_schema)], response_model=ProcessSchema)
async def get_process_schema( async def get_process_schema_endpoint(
process_schema_id: int, process_schema_id: int,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),
@@ -101,8 +106,8 @@ async def get_process_schema(
return process_schema_validation return process_schema_validation
@api_router.post("", dependencies=[Depends(bearer_schema)], response_model=ProcessSchema) @api_router.post("", dependencies=[Depends(bearer_schema)], response_model=ProcessSchemaResponse)
async def create_processschema( async def create_processschema_endpoint(
process_schema: ProcessSchemaUpdate, process_schema: ProcessSchemaUpdate,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),
@@ -111,9 +116,50 @@ async def create_processschema(
process_schema_validation = await get_process_schema_by_title(connection, process_schema.title) process_schema_validation = await get_process_schema_by_title(connection, process_schema.title)
if process_schema_validation is None: if process_schema_validation is None:
await create_process_schema(connection, process_schema, user_validation.id) await create_process_schema(connection, process_schema, user_validation.id)
process_schema_new = await get_process_schema_by_title(connection, process_schema.title) process_schema_new = await get_process_schema_by_title(connection, process_schema.title)
return process_schema_new
start_node_data = StartNodeData(
ps_id=process_schema_new.id,
node_type=NodeType.START.value
)
start_node_links = {}
start_node = VorkNodeStart(data=start_node_data.model_dump(), links=start_node_links)
validated_start_schema = start_node.validate()
db_start_schema = await create_ps_node_schema(connection, validated_start_schema, user_validation.id)
node = ProcessSchemaSettingsNode(
id=db_start_schema.id,
node_type=NodeType.START.value,
data=validated_start_schema.data.model_dump(),
from_node=None,
links=None)
settings_dict = {"node": node.model_dump(mode='json')}
await update_process_schema_settings_by_id(connection, process_schema_new.id, settings_dict)
process_schema_new = await get_process_schema_by_title(connection, process_schema.title)
ps_node_front_response = Ps_NodeFrontResponse(
description=None,
node=Ps_NodeFrontResponseNode(
id=db_start_schema.id,
node_type=NodeType.START.value,
data=validated_start_schema.data.model_dump()),
link=None)
response_data = {
"process_schema": process_schema_new.model_dump(mode='json'),
"node_start":ps_node_front_response.model_dump(mode='json')}
return response_data
else: else:
raise HTTPException( raise HTTPException(
@@ -122,7 +168,7 @@ async def create_processschema(
@api_router.put("/{process_schema_id}", dependencies=[Depends(bearer_schema)], response_model=ProcessSchema) @api_router.put("/{process_schema_id}", dependencies=[Depends(bearer_schema)], response_model=ProcessSchema)
async def update_process_schema( async def update_process_schema_endpoint(
process_schema_id: int, process_schema_id: int,
process_schema_update: ProcessSchemaUpdate, process_schema_update: ProcessSchemaUpdate,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
@@ -150,7 +196,7 @@ async def update_process_schema(
@api_router.delete("/{process_schema_id}", dependencies=[Depends(bearer_schema)], response_model=ProcessSchema) @api_router.delete("/{process_schema_id}", dependencies=[Depends(bearer_schema)], response_model=ProcessSchema)
async def delete_process_schema( async def delete_process_schema_endpoint(
process_schema_id: int, process_schema_id: int,
connection: AsyncConnection = Depends(get_connection_dep), connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user), current_user=Depends(get_current_user),

View File

@@ -4,18 +4,14 @@ from fastapi import (
HTTPException, HTTPException,
status, status,
) )
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.connection.session import get_connection_dep from api.db.connection.session import get_connection_dep
from api.db.logic.account import get_user_by_id, update_user_by_id, get_user_by_login from api.db.logic.account import get_user_by_id, get_user_by_login, update_user_by_id
from api.schemas.base import bearer_schema
from api.services.auth import get_current_user
from api.schemas.endpoints.account import UserUpdate
from api.schemas.account.account import User from api.schemas.account.account import User
from api.schemas.base import bearer_schema
from api.schemas.endpoints.account import UserUpdate
from api.services.auth import get_current_user
api_router = APIRouter( api_router = APIRouter(
prefix="/profile", prefix="/profile",

View File

@@ -0,0 +1,116 @@
from fastapi import APIRouter, Depends, HTTPException,status
from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.connection.session import get_connection_dep
from api.db.logic.account import get_user_by_login
from api.schemas.base import bearer_schema
from api.schemas.process.process_schema import ProcessSchemaSettingsNodeLink, ProcessSchemaSettingsNode
from api.schemas.process.ps_node import Ps_NodeFrontResponseNode, Ps_NodeRequest
from api.schemas.process.ps_node import Ps_NodeFrontResponse
from api.services.auth import get_current_user
from api.db.logic.ps_node import create_ps_node_schema
from api.db.logic.node_link import get_last_link_name_by_node_id, create_node_link_schema
from api.db.logic.process_schema import update_process_schema_settings_by_id
from core import VorkNodeRegistry, VorkNodeLink
from model_nodes import VorkNodeLinkData
api_router = APIRouter(
prefix="/ps_node",
tags=["ps node"],
)
@api_router.post("", dependencies=[Depends(bearer_schema)],response_model=Ps_NodeFrontResponse)
async def create_ps_node_endpoint(
ps_node: Ps_NodeRequest,
connection: AsyncConnection = Depends(get_connection_dep),
current_user=Depends(get_current_user),
):
user_validation = await get_user_by_login(connection, current_user)
registery = VorkNodeRegistry()
vork_node = registery.get(ps_node.data["node_type"])
if vork_node is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Node not found")
node_descriptor = vork_node.form()
try:
node_instance = vork_node(data=ps_node.data, links=ps_node.links)
node_instance_validated = node_instance.validate()
except Exception as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
db_ps_node = await create_ps_node_schema(connection, node_instance_validated, user_validation.id)
link_name = await get_last_link_name_by_node_id(connection, db_ps_node.ps_id)
link_data = VorkNodeLinkData(
parent_port_number=node_instance_validated.parent_port_number,
to_id=db_ps_node.id,
from_id=node_instance_validated.parent_id,
last_link_name=link_name)
link = VorkNodeLink(data=link_data.model_dump())
validated_link = link.validate()
db_node_link = await create_node_link_schema(connection, validated_link, user_validation.id)
links_settings = ProcessSchemaSettingsNodeLink(
id=db_node_link.id,
link_name=db_node_link.link_name,
parent_port_number=db_node_link.link_point_id,
from_id=db_node_link.node_id,
to_id=db_node_link.next_node_id,
)
node_settings = ProcessSchemaSettingsNode(
id=db_ps_node.id,
node_type=db_ps_node.node_type,
data=node_instance_validated.data.model_dump(),
from_node=None,
links=links_settings)
settings_dict = {"node": node_settings.model_dump(mode='json')}
await update_process_schema_settings_by_id(connection, db_ps_node.ps_id, settings_dict)
ps_node_front_response = Ps_NodeFrontResponse(
description=node_descriptor.model_dump(),
node=Ps_NodeFrontResponseNode(
id=db_ps_node.id,
node_type=db_ps_node.node_type,
data=node_instance_validated.data.model_dump()),
link=links_settings)
return ps_node_front_response.model_dump(mode='json')

View File

@@ -1,8 +1,8 @@
import datetime
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
from orm.tables.account import AccountRole, AccountStatus
from pydantic import EmailStr, Field from pydantic import EmailStr, Field
from api.db.tables.account import AccountRole, AccountStatus
from api.schemas.base import Base from api.schemas.base import Base

View File

@@ -1,8 +1,8 @@
import datetime
from typing import Optional
from pydantic import Field
from datetime import datetime from datetime import datetime
from api.db.tables.account import KeyType, KeyStatus from typing import Optional
from orm.tables.account import KeyStatus, KeyType
from pydantic import Field
from api.schemas.base import Base from api.schemas.base import Base

View File

@@ -1,9 +1,9 @@
from datetime import datetime from datetime import datetime
from typing import List, Optional, Dict from typing import Dict, List, Optional
from orm.tables.account import AccountRole, AccountStatus
from pydantic import EmailStr, Field, TypeAdapter from pydantic import EmailStr, Field, TypeAdapter
from api.db.tables.account import AccountRole, AccountStatus
from api.schemas.base import Base from api.schemas.base import Base

View File

@@ -1,6 +1,8 @@
from typing import Optional from typing import Optional
from orm.tables.account import KeyStatus, KeyType
from pydantic import Field from pydantic import Field
from api.db.tables.account import KeyType, KeyStatus
from api.schemas.base import Base from api.schemas.base import Base

View File

@@ -1,5 +1,6 @@
from api.schemas.base import Base from api.schemas.base import Base
# Таблица для получения информации из запроса # Таблица для получения информации из запроса

View File

@@ -1,10 +1,10 @@
from pydantic import Field, TypeAdapter
from typing import Optional, Dict, Any, List
from datetime import datetime from datetime import datetime
from typing import Any, Dict, List, Optional
from orm.tables.events import EventState, EventStatus
from pydantic import Field, TypeAdapter
from api.schemas.base import Base from api.schemas.base import Base
from api.db.tables.events import EventState, EventStatus
class ListEventUpdate(Base): class ListEventUpdate(Base):

View File

@@ -1,10 +1,10 @@
from pydantic import Field, TypeAdapter
from typing import Optional, Dict, Any, List
from datetime import datetime from datetime import datetime
from typing import Any, Dict, List, Optional
from orm.tables.process import ProcessStatus
from pydantic import Field, TypeAdapter
from api.schemas.base import Base from api.schemas.base import Base
from api.db.tables.process import ProcessStatus
class ProcessSchemaUpdate(Base): class ProcessSchemaUpdate(Base):

View File

@@ -1,9 +1,10 @@
from pydantic import Field
from typing import Dict, Any
from datetime import datetime from datetime import datetime
from typing import Any, Dict
from orm.tables.events import EventState, EventStatus
from pydantic import Field
from api.schemas.base import Base from api.schemas.base import Base
from api.db.tables.events import EventState, EventStatus
class ListEvent(Base): class ListEvent(Base):

View File

@@ -1,15 +1,17 @@
from pydantic import Field
from typing import Dict, Any
from datetime import datetime from datetime import datetime
from typing import Any, Dict
from orm.tables.process import NodeStatus
from pydantic import Field
from api.schemas.base import Base from api.schemas.base import Base
from api.db.tables.process import NodeStatus
class MyModel(Base): class NodeLink(Base):
id: int id: int
link_name: str = Field(..., max_length=20) link_name: str = Field(..., max_length=20)
node_id: int node_id: int
link_point_id: int
next_node_id: int next_node_id: int
settings: Dict[str, Any] settings: Dict[str, Any]
creator_id: int creator_id: int

View File

@@ -1,9 +1,11 @@
from pydantic import Field
from typing import Dict, Any
from datetime import datetime from datetime import datetime
from typing import Any, Dict, Optional
from orm.tables.process import ProcessStatus, NodeType
from pydantic import Field
from api.schemas.base import Base from api.schemas.base import Base
from api.db.tables.process import ProcessStatus from api.schemas.process.ps_node import Ps_NodeFrontResponse
class ProcessSchema(Base): class ProcessSchema(Base):
@@ -15,3 +17,24 @@ class ProcessSchema(Base):
created_at: datetime created_at: datetime
settings: Dict[str, Any] settings: Dict[str, Any]
status: ProcessStatus status: ProcessStatus
class ProcessSchemaSettingsNodeLink(Base):
id: int
link_name: str
parent_port_number: int
from_id: int
to_id: int
class ProcessSchemaSettingsNode(Base):
id: int
node_type: NodeType
from_node: Optional[Dict[str, Any]] = None
data: Dict[str, Any]# Переименовано с 'from' на 'from_node'
links: Optional[ProcessSchemaSettingsNodeLink] = None
class ProcessSchemaResponse(Base):
process_schema: ProcessSchema
node_start: Ps_NodeFrontResponse

View File

@@ -1,5 +1,5 @@
from typing import Dict, Any
from datetime import datetime from datetime import datetime
from typing import Any, Dict
from api.schemas.base import Base from api.schemas.base import Base

View File

@@ -1,15 +1,42 @@
from datetime import datetime from datetime import datetime
from typing import Dict, Any from typing import Any, Dict, Optional
from orm.tables.process import NodeStatus, NodeType
from pydantic import Field
from api.schemas.base import Base from api.schemas.base import Base
from api.db.tables.process import NodeType, NodeStatus
class Ps_NodeRequest(Base):
data: Dict[str, Any]
links: Dict[str, Any]
class Ps_Node(Base): class Ps_Node(Base):
id: int id: int
ps_id: int ps_id: int
node_type: NodeType node_type: NodeType
settings: dict settings: dict
creator_id: Dict[str, Any] creator_id: int
created_at: datetime created_at: datetime
status: NodeStatus status: NodeStatus
class Ps_NodeFrontResponseLink(Base):
id: int
link_name: str
parent_port_number: int
from_id: int
to_id: int
class Ps_NodeFrontResponseNode(Base):
id: int
node_type: NodeType
data: Dict[str, Any]# Переименовано с 'from' на 'from_node'
class Ps_NodeFrontResponse(Base):
description: Optional[Dict[str, Any]] = None
node: Optional[Ps_NodeFrontResponseNode] = None
link: Optional[Ps_NodeFrontResponseLink] = None

View File

@@ -1,10 +1,10 @@
from typing import Optional from typing import Optional
from fastapi import HTTPException, Request from fastapi import HTTPException, Request
from orm.tables.account import AccountStatus
from sqlalchemy.ext.asyncio import AsyncConnection from sqlalchemy.ext.asyncio import AsyncConnection
from api.db.logic.auth import get_user from api.db.logic.auth import get_user
from api.db.tables.account import AccountStatus
from api.schemas.endpoints.account import AllUser from api.schemas.endpoints.account import AllUser
from api.utils.hasher import hasher from api.utils.hasher import hasher

View File

@@ -1,15 +1,15 @@
from fastapi_jwt_auth import AuthJWT import re
from starlette.middleware.base import BaseHTTPMiddleware from re import escape
from fastapi import ( from fastapi import (
Request, Request,
status, status,
) )
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from api.config import get_settings from fastapi_jwt_auth import AuthJWT
from starlette.middleware.base import BaseHTTPMiddleware
import re from api.config import get_settings
from re import escape
class MiddlewareAccessTokenValidadtion(BaseHTTPMiddleware): class MiddlewareAccessTokenValidadtion(BaseHTTPMiddleware):

View File

@@ -2,8 +2,9 @@ from fastapi import (
HTTPException, HTTPException,
status, status,
) )
from orm.tables.account import AccountRole
from api.db.logic.account import get_user_by_login from api.db.logic.account import get_user_by_login
from api.db.tables.account import AccountRole
async def db_user_role_validation(connection, current_user): async def db_user_role_validation(connection, current_user):

View File

@@ -1,8 +1,9 @@
import asyncio import asyncio
import os import os
from orm.tables.account import account_keyring_table, account_table, AccountRole, KeyStatus, KeyType
from api.db.connection.session import get_connection from api.db.connection.session import get_connection
from api.db.tables.account import account_keyring_table, account_table, AccountRole, KeyStatus, KeyType
from api.utils.hasher import hasher from api.utils.hasher import hasher
from api.utils.key_id_gen import KeyIdGenerator from api.utils.key_id_gen import KeyIdGenerator

152
api/poetry.lock generated
View File

@@ -227,6 +227,26 @@ files = [
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
] ]
[[package]]
name = "core-library"
version = "0.1.0"
description = "Abstract classes library for the Vorkout project"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = []
develop = false
[package.dependencies]
pydantic = ">=2.0.0,<3.0.0"
sqlalchemy = ">=2.0.43,<3.0.0"
[package.source]
type = "git"
url = "https://gitea.heado.ru/Vorkout/core.git"
reference = "VORKOUT-18"
resolved_reference = "a5a52a64ef6e456e19586e0834d9531d4a88b0db"
[[package]] [[package]]
name = "cryptography" name = "cryptography"
version = "44.0.2" version = "44.0.2"
@@ -1416,83 +1436,83 @@ files = [
[[package]] [[package]]
name = "sqlalchemy" name = "sqlalchemy"
version = "2.0.39" version = "2.0.43"
description = "Database Abstraction Library" description = "Database Abstraction Library"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
groups = ["main"] groups = ["main"]
files = [ files = [
{file = "SQLAlchemy-2.0.39-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:66a40003bc244e4ad86b72abb9965d304726d05a939e8c09ce844d27af9e6d37"}, {file = "SQLAlchemy-2.0.43-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:21ba7a08a4253c5825d1db389d4299f64a100ef9800e4624c8bf70d8f136e6ed"},
{file = "SQLAlchemy-2.0.39-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67de057fbcb04a066171bd9ee6bcb58738d89378ee3cabff0bffbf343ae1c787"}, {file = "SQLAlchemy-2.0.43-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11b9503fa6f8721bef9b8567730f664c5a5153d25e247aadc69247c4bc605227"},
{file = "SQLAlchemy-2.0.39-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:533e0f66c32093a987a30df3ad6ed21170db9d581d0b38e71396c49718fbb1ca"}, {file = "SQLAlchemy-2.0.43-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07097c0a1886c150ef2adba2ff7437e84d40c0f7dcb44a2c2b9c905ccfc6361c"},
{file = "SQLAlchemy-2.0.39-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7399d45b62d755e9ebba94eb89437f80512c08edde8c63716552a3aade61eb42"}, {file = "SQLAlchemy-2.0.43-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:cdeff998cb294896a34e5b2f00e383e7c5c4ef3b4bfa375d9104723f15186443"},
{file = "SQLAlchemy-2.0.39-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:788b6ff6728072b313802be13e88113c33696a9a1f2f6d634a97c20f7ef5ccce"}, {file = "SQLAlchemy-2.0.43-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:bcf0724a62a5670e5718957e05c56ec2d6850267ea859f8ad2481838f889b42c"},
{file = "SQLAlchemy-2.0.39-cp37-cp37m-win32.whl", hash = "sha256:01da15490c9df352fbc29859d3c7ba9cd1377791faeeb47c100832004c99472c"}, {file = "SQLAlchemy-2.0.43-cp37-cp37m-win32.whl", hash = "sha256:c697575d0e2b0a5f0433f679bda22f63873821d991e95a90e9e52aae517b2e32"},
{file = "SQLAlchemy-2.0.39-cp37-cp37m-win_amd64.whl", hash = "sha256:f2bcb085faffcacf9319b1b1445a7e1cfdc6fb46c03f2dce7bc2d9a4b3c1cdc5"}, {file = "SQLAlchemy-2.0.43-cp37-cp37m-win_amd64.whl", hash = "sha256:d34c0f6dbefd2e816e8f341d0df7d4763d382e3f452423e752ffd1e213da2512"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b761a6847f96fdc2d002e29e9e9ac2439c13b919adfd64e8ef49e75f6355c548"}, {file = "sqlalchemy-2.0.43-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70322986c0c699dca241418fcf18e637a4369e0ec50540a2b907b184c8bca069"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0d7e3866eb52d914aea50c9be74184a0feb86f9af8aaaa4daefe52b69378db0b"}, {file = "sqlalchemy-2.0.43-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87accdbba88f33efa7b592dc2e8b2a9c2cdbca73db2f9d5c510790428c09c154"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:995c2bacdddcb640c2ca558e6760383dcdd68830160af92b5c6e6928ffd259b4"}, {file = "sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c00e7845d2f692ebfc7d5e4ec1a3fd87698e4337d09e58d6749a16aedfdf8612"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:344cd1ec2b3c6bdd5dfde7ba7e3b879e0f8dd44181f16b895940be9b842fd2b6"}, {file = "sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:022e436a1cb39b13756cf93b48ecce7aa95382b9cfacceb80a7d263129dfd019"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5dfbc543578058c340360f851ddcecd7a1e26b0d9b5b69259b526da9edfa8875"}, {file = "sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c5e73ba0d76eefc82ec0219d2301cb33bfe5205ed7a2602523111e2e56ccbd20"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3395e7ed89c6d264d38bea3bfb22ffe868f906a7985d03546ec7dc30221ea980"}, {file = "sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9c2e02f06c68092b875d5cbe4824238ab93a7fa35d9c38052c033f7ca45daa18"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-win32.whl", hash = "sha256:bf555f3e25ac3a70c67807b2949bfe15f377a40df84b71ab2c58d8593a1e036e"}, {file = "sqlalchemy-2.0.43-cp310-cp310-win32.whl", hash = "sha256:e7a903b5b45b0d9fa03ac6a331e1c1d6b7e0ab41c63b6217b3d10357b83c8b00"},
{file = "SQLAlchemy-2.0.39-cp38-cp38-win_amd64.whl", hash = "sha256:463ecfb907b256e94bfe7bcb31a6d8c7bc96eca7cbe39803e448a58bb9fcad02"}, {file = "sqlalchemy-2.0.43-cp310-cp310-win_amd64.whl", hash = "sha256:4bf0edb24c128b7be0c61cd17eef432e4bef507013292415f3fb7023f02b7d4b"},
{file = "sqlalchemy-2.0.39-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6827f8c1b2f13f1420545bd6d5b3f9e0b85fe750388425be53d23c760dcf176b"}, {file = "sqlalchemy-2.0.43-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:52d9b73b8fb3e9da34c2b31e6d99d60f5f99fd8c1225c9dad24aeb74a91e1d29"},
{file = "sqlalchemy-2.0.39-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9f119e7736967c0ea03aff91ac7d04555ee038caf89bb855d93bbd04ae85b41"}, {file = "sqlalchemy-2.0.43-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f42f23e152e4545157fa367b2435a1ace7571cab016ca26038867eb7df2c3631"},
{file = "sqlalchemy-2.0.39-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4600c7a659d381146e1160235918826c50c80994e07c5b26946a3e7ec6c99249"}, {file = "sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fb1a8c5438e0c5ea51afe9c6564f951525795cf432bed0c028c1cb081276685"},
{file = "sqlalchemy-2.0.39-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a06e6c8e31c98ddc770734c63903e39f1947c9e3e5e4bef515c5491b7737dde"}, {file = "sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db691fa174e8f7036afefe3061bc40ac2b770718be2862bfb03aabae09051aca"},
{file = "sqlalchemy-2.0.39-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c4c433f78c2908ae352848f56589c02b982d0e741b7905228fad628999799de4"}, {file = "sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2b3b4927d0bc03d02ad883f402d5de201dbc8894ac87d2e981e7d87430e60d"},
{file = "sqlalchemy-2.0.39-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7bd5c5ee1448b6408734eaa29c0d820d061ae18cb17232ce37848376dcfa3e92"}, {file = "sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d3d9b904ad4a6b175a2de0738248822f5ac410f52c2fd389ada0b5262d6a1e3"},
{file = "sqlalchemy-2.0.39-cp310-cp310-win32.whl", hash = "sha256:87a1ce1f5e5dc4b6f4e0aac34e7bb535cb23bd4f5d9c799ed1633b65c2bcad8c"}, {file = "sqlalchemy-2.0.43-cp311-cp311-win32.whl", hash = "sha256:5cda6b51faff2639296e276591808c1726c4a77929cfaa0f514f30a5f6156921"},
{file = "sqlalchemy-2.0.39-cp310-cp310-win_amd64.whl", hash = "sha256:871f55e478b5a648c08dd24af44345406d0e636ffe021d64c9b57a4a11518304"}, {file = "sqlalchemy-2.0.43-cp311-cp311-win_amd64.whl", hash = "sha256:c5d1730b25d9a07727d20ad74bc1039bbbb0a6ca24e6769861c1aa5bf2c4c4a8"},
{file = "sqlalchemy-2.0.39-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a28f9c238f1e143ff42ab3ba27990dfb964e5d413c0eb001b88794c5c4a528a9"}, {file = "sqlalchemy-2.0.43-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:20d81fc2736509d7a2bd33292e489b056cbae543661bb7de7ce9f1c0cd6e7f24"},
{file = "sqlalchemy-2.0.39-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:08cf721bbd4391a0e765fe0fe8816e81d9f43cece54fdb5ac465c56efafecb3d"}, {file = "sqlalchemy-2.0.43-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b9fc27650ff5a2c9d490c13c14906b918b0de1f8fcbb4c992712d8caf40e83"},
{file = "sqlalchemy-2.0.39-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a8517b6d4005facdbd7eb4e8cf54797dbca100a7df459fdaff4c5123265c1cd"}, {file = "sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6772e3ca8a43a65a37c88e2f3e2adfd511b0b1da37ef11ed78dea16aeae85bd9"},
{file = "sqlalchemy-2.0.39-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b2de1523d46e7016afc7e42db239bd41f2163316935de7c84d0e19af7e69538"}, {file = "sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a113da919c25f7f641ffbd07fbc9077abd4b3b75097c888ab818f962707eb48"},
{file = "sqlalchemy-2.0.39-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:412c6c126369ddae171c13987b38df5122cb92015cba6f9ee1193b867f3f1530"}, {file = "sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4286a1139f14b7d70141c67a8ae1582fc2b69105f1b09d9573494eb4bb4b2687"},
{file = "sqlalchemy-2.0.39-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b35e07f1d57b79b86a7de8ecdcefb78485dab9851b9638c2c793c50203b2ae8"}, {file = "sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:529064085be2f4d8a6e5fab12d36ad44f1909a18848fcfbdb59cc6d4bbe48efe"},
{file = "sqlalchemy-2.0.39-cp311-cp311-win32.whl", hash = "sha256:3eb14ba1a9d07c88669b7faf8f589be67871d6409305e73e036321d89f1d904e"}, {file = "sqlalchemy-2.0.43-cp312-cp312-win32.whl", hash = "sha256:b535d35dea8bbb8195e7e2b40059e2253acb2b7579b73c1b432a35363694641d"},
{file = "sqlalchemy-2.0.39-cp311-cp311-win_amd64.whl", hash = "sha256:78f1b79132a69fe8bd6b5d91ef433c8eb40688ba782b26f8c9f3d2d9ca23626f"}, {file = "sqlalchemy-2.0.43-cp312-cp312-win_amd64.whl", hash = "sha256:1c6d85327ca688dbae7e2b06d7d84cfe4f3fffa5b5f9e21bb6ce9d0e1a0e0e0a"},
{file = "sqlalchemy-2.0.39-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c457a38351fb6234781d054260c60e531047e4d07beca1889b558ff73dc2014b"}, {file = "sqlalchemy-2.0.43-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e7c08f57f75a2bb62d7ee80a89686a5e5669f199235c6d1dac75cd59374091c3"},
{file = "sqlalchemy-2.0.39-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:018ee97c558b499b58935c5a152aeabf6d36b3d55d91656abeb6d93d663c0c4c"}, {file = "sqlalchemy-2.0.43-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:14111d22c29efad445cd5021a70a8b42f7d9152d8ba7f73304c4d82460946aaa"},
{file = "sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5493a8120d6fc185f60e7254fc056a6742f1db68c0f849cfc9ab46163c21df47"}, {file = "sqlalchemy-2.0.43-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b27b56eb2f82653168cefe6cb8e970cdaf4f3a6cb2c5e3c3c1cf3158968ff9"},
{file = "sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2cf5b5ddb69142511d5559c427ff00ec8c0919a1e6c09486e9c32636ea2b9dd"}, {file = "sqlalchemy-2.0.43-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c5a9da957c56e43d72126a3f5845603da00e0293720b03bde0aacffcf2dc04f"},
{file = "sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f03143f8f851dd8de6b0c10784363712058f38209e926723c80654c1b40327a"}, {file = "sqlalchemy-2.0.43-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d79f9fdc9584ec83d1b3c75e9f4595c49017f5594fee1a2217117647225d738"},
{file = "sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06205eb98cb3dd52133ca6818bf5542397f1dd1b69f7ea28aa84413897380b06"}, {file = "sqlalchemy-2.0.43-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9df7126fd9db49e3a5a3999442cc67e9ee8971f3cb9644250107d7296cb2a164"},
{file = "sqlalchemy-2.0.39-cp312-cp312-win32.whl", hash = "sha256:7f5243357e6da9a90c56282f64b50d29cba2ee1f745381174caacc50d501b109"}, {file = "sqlalchemy-2.0.43-cp313-cp313-win32.whl", hash = "sha256:7f1ac7828857fcedb0361b48b9ac4821469f7694089d15550bbcf9ab22564a1d"},
{file = "sqlalchemy-2.0.39-cp312-cp312-win_amd64.whl", hash = "sha256:2ed107331d188a286611cea9022de0afc437dd2d3c168e368169f27aa0f61338"}, {file = "sqlalchemy-2.0.43-cp313-cp313-win_amd64.whl", hash = "sha256:971ba928fcde01869361f504fcff3b7143b47d30de188b11c6357c0505824197"},
{file = "sqlalchemy-2.0.39-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe193d3ae297c423e0e567e240b4324d6b6c280a048e64c77a3ea6886cc2aa87"}, {file = "sqlalchemy-2.0.43-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4e6aeb2e0932f32950cf56a8b4813cb15ff792fc0c9b3752eaf067cfe298496a"},
{file = "sqlalchemy-2.0.39-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79f4f502125a41b1b3b34449e747a6abfd52a709d539ea7769101696bdca6716"}, {file = "sqlalchemy-2.0.43-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:61f964a05356f4bca4112e6334ed7c208174511bd56e6b8fc86dad4d024d4185"},
{file = "sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a10ca7f8a1ea0fd5630f02feb055b0f5cdfcd07bb3715fc1b6f8cb72bf114e4"}, {file = "sqlalchemy-2.0.43-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46293c39252f93ea0910aababa8752ad628bcce3a10d3f260648dd472256983f"},
{file = "sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6b0a1c7ed54a5361aaebb910c1fa864bae34273662bb4ff788a527eafd6e14d"}, {file = "sqlalchemy-2.0.43-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:136063a68644eca9339d02e6693932116f6a8591ac013b0014479a1de664e40a"},
{file = "sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52607d0ebea43cf214e2ee84a6a76bc774176f97c5a774ce33277514875a718e"}, {file = "sqlalchemy-2.0.43-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6e2bf13d9256398d037fef09fd8bf9b0bf77876e22647d10761d35593b9ac547"},
{file = "sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c08a972cbac2a14810463aec3a47ff218bb00c1a607e6689b531a7c589c50723"}, {file = "sqlalchemy-2.0.43-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:44337823462291f17f994d64282a71c51d738fc9ef561bf265f1d0fd9116a782"},
{file = "sqlalchemy-2.0.39-cp313-cp313-win32.whl", hash = "sha256:23c5aa33c01bd898f879db158537d7e7568b503b15aad60ea0c8da8109adf3e7"}, {file = "sqlalchemy-2.0.43-cp38-cp38-win32.whl", hash = "sha256:13194276e69bb2af56198fef7909d48fd34820de01d9c92711a5fa45497cc7ed"},
{file = "sqlalchemy-2.0.39-cp313-cp313-win_amd64.whl", hash = "sha256:4dabd775fd66cf17f31f8625fc0e4cfc5765f7982f94dc09b9e5868182cb71c0"}, {file = "sqlalchemy-2.0.43-cp38-cp38-win_amd64.whl", hash = "sha256:334f41fa28de9f9be4b78445e68530da3c5fa054c907176460c81494f4ae1f5e"},
{file = "sqlalchemy-2.0.39-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2600a50d590c22d99c424c394236899ba72f849a02b10e65b4c70149606408b5"}, {file = "sqlalchemy-2.0.43-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb5c832cc30663aeaf5e39657712f4c4241ad1f638d487ef7216258f6d41fe7"},
{file = "sqlalchemy-2.0.39-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4eff9c270afd23e2746e921e80182872058a7a592017b2713f33f96cc5f82e32"}, {file = "sqlalchemy-2.0.43-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11f43c39b4b2ec755573952bbcc58d976779d482f6f832d7f33a8d869ae891bf"},
{file = "sqlalchemy-2.0.39-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7332868ce891eda48896131991f7f2be572d65b41a4050957242f8e935d5d7"}, {file = "sqlalchemy-2.0.43-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:413391b2239db55be14fa4223034d7e13325a1812c8396ecd4f2c08696d5ccad"},
{file = "sqlalchemy-2.0.39-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:125a7763b263218a80759ad9ae2f3610aaf2c2fbbd78fff088d584edf81f3782"}, {file = "sqlalchemy-2.0.43-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c379e37b08c6c527181a397212346be39319fb64323741d23e46abd97a400d34"},
{file = "sqlalchemy-2.0.39-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:04545042969833cb92e13b0a3019549d284fd2423f318b6ba10e7aa687690a3c"}, {file = "sqlalchemy-2.0.43-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:03d73ab2a37d9e40dec4984d1813d7878e01dbdc742448d44a7341b7a9f408c7"},
{file = "sqlalchemy-2.0.39-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:805cb481474e111ee3687c9047c5f3286e62496f09c0e82e8853338aaaa348f8"}, {file = "sqlalchemy-2.0.43-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8cee08f15d9e238ede42e9bbc1d6e7158d0ca4f176e4eab21f88ac819ae3bd7b"},
{file = "sqlalchemy-2.0.39-cp39-cp39-win32.whl", hash = "sha256:34d5c49f18778a3665d707e6286545a30339ad545950773d43977e504815fa70"}, {file = "sqlalchemy-2.0.43-cp39-cp39-win32.whl", hash = "sha256:b3edaec7e8b6dc5cd94523c6df4f294014df67097c8217a89929c99975811414"},
{file = "sqlalchemy-2.0.39-cp39-cp39-win_amd64.whl", hash = "sha256:35e72518615aa5384ef4fae828e3af1b43102458b74a8c481f69af8abf7e802a"}, {file = "sqlalchemy-2.0.43-cp39-cp39-win_amd64.whl", hash = "sha256:227119ce0a89e762ecd882dc661e0aa677a690c914e358f0dd8932a2e8b2765b"},
{file = "sqlalchemy-2.0.39-py3-none-any.whl", hash = "sha256:a1c6b0a5e3e326a466d809b651c63f278b1256146a377a528b6938a279da334f"}, {file = "sqlalchemy-2.0.43-py3-none-any.whl", hash = "sha256:1681c21dd2ccee222c2fe0bef671d1aef7c504087c9c4e800371cfcc8ac966fc"},
{file = "sqlalchemy-2.0.39.tar.gz", hash = "sha256:5d2d1fe548def3267b4c70a8568f108d1fed7cbbeccb9cc166e05af2abc25c22"}, {file = "sqlalchemy-2.0.43.tar.gz", hash = "sha256:788bfcef6787a7764169cfe9859fe425bf44559619e1d9f56f5bddf2ebf6f417"},
] ]
[package.dependencies] [package.dependencies]
aiomysql = {version = ">=0.2.0", optional = true, markers = "extra == \"aiomysql\""} aiomysql = {version = ">=0.2.0", optional = true, markers = "extra == \"aiomysql\""}
greenlet = {version = "!=0.4.17", optional = true, markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\") or extra == \"aiomysql\""} greenlet = {version = ">=1", optional = true, markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\") or extra == \"aiomysql\""}
pymysql = {version = "*", optional = true, markers = "extra == \"pymysql\""} pymysql = {version = "*", optional = true, markers = "extra == \"pymysql\""}
typing-extensions = ">=4.6.0" typing-extensions = ">=4.6.0"
[package.extras] [package.extras]
aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"]
aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] aioodbc = ["aioodbc", "greenlet (>=1)"]
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"]
asyncio = ["greenlet (!=0.4.17)"] asyncio = ["greenlet (>=1)"]
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"]
mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"]
mssql = ["pyodbc"] mssql = ["pyodbc"]
mssql-pymssql = ["pymssql"] mssql-pymssql = ["pymssql"]
@@ -1503,7 +1523,7 @@ mysql-connector = ["mysql-connector-python"]
oracle = ["cx_oracle (>=8)"] oracle = ["cx_oracle (>=8)"]
oracle-oracledb = ["oracledb (>=1.0.1)"] oracle-oracledb = ["oracledb (>=1.0.1)"]
postgresql = ["psycopg2 (>=2.7)"] postgresql = ["psycopg2 (>=2.7)"]
postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"]
postgresql-pg8000 = ["pg8000 (>=1.29.1)"] postgresql-pg8000 = ["pg8000 (>=1.29.1)"]
postgresql-psycopg = ["psycopg (>=3.0.7)"] postgresql-psycopg = ["psycopg (>=3.0.7)"]
postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2binary = ["psycopg2-binary"]
@@ -1933,4 +1953,4 @@ propcache = ">=0.2.0"
[metadata] [metadata]
lock-version = "2.1" lock-version = "2.1"
python-versions = ">=3.11,<4.0" python-versions = ">=3.11,<4.0"
content-hash = "5ed129fde2c5d7b3518fbb2fe2ce79f0bad2aa1060304d45a7bc26d35f7ab46b" content-hash = "abdeab9600b3023bd1dcf38b64df49bdd3f9baea99b72aa3bb3d3d48f05ed0c2"

View File

@@ -17,6 +17,7 @@ dependencies = [
"pydantic[email] (>=2.11.3,<3.0.0)", "pydantic[email] (>=2.11.3,<3.0.0)",
"python-multipart (>=0.0.20,<0.0.21)", "python-multipart (>=0.0.20,<0.0.21)",
"fastapi-jwt-auth @ git+https://github.com/vvpreo/fastapi-jwt-auth", "fastapi-jwt-auth @ git+https://github.com/vvpreo/fastapi-jwt-auth",
"core-library @ git+https://gitea.heado.ru/Vorkout/core.git@VORKOUT-18",
] ]