New file |
| | |
| | | """token table |
| | | |
| | | Revision ID: 07b5185945e0 |
| | | Revises: 4b3a7c69ceac |
| | | Create Date: 2024-12-06 16:27:30.329519 |
| | | |
| | | """ |
| | | from typing import Sequence, Union |
| | | |
| | | from alembic import op |
| | | import sqlalchemy as sa |
| | | |
| | | |
| | | # revision identifiers, used by Alembic. |
| | | revision: str = '07b5185945e0' |
| | | down_revision: Union[str, None] = '4b3a7c69ceac' |
| | | branch_labels: Union[str, Sequence[str], None] = None |
| | | depends_on: Union[str, Sequence[str], None] = None |
| | | |
| | | |
| | | def upgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | pass |
| | | # ### end Alembic commands ### |
| | | |
| | | |
| | | def downgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | pass |
| | | # ### end Alembic commands ### |
New file |
| | |
| | | """init table |
| | | |
| | | Revision ID: 4b3a7c69ceac |
| | | Revises: |
| | | Create Date: 2024-12-06 16:12:04.760402 |
| | | |
| | | """ |
| | | 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 = '4b3a7c69ceac' |
| | | down_revision: Union[str, None] = None |
| | | branch_labels: Union[str, Sequence[str], None] = None |
| | | depends_on: Union[str, Sequence[str], None] = None |
| | | |
| | | |
| | | def upgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | op.drop_index('ix_user_test_id', table_name='user_test') |
| | | op.drop_index('ix_user_test_username', table_name='user_test') |
| | | op.drop_table('user_test') |
| | | op.alter_column('user', 'ragflow_id', |
| | | existing_type=mysql.VARCHAR(length=32), |
| | | nullable=True) |
| | | op.alter_column('user', 'bisheng_id', |
| | | existing_type=mysql.INTEGER(), |
| | | nullable=True) |
| | | op.alter_column('user', 'status', |
| | | existing_type=mysql.VARCHAR(length=10), |
| | | nullable=True, |
| | | existing_server_default=sa.text("'1'")) |
| | | op.alter_column('user', 'permission', |
| | | existing_type=mysql.VARCHAR(length=16), |
| | | nullable=True, |
| | | existing_server_default=sa.text("'general'")) |
| | | op.drop_column('user', 'updated_at11') |
| | | # ### end Alembic commands ### |
| | | |
| | | |
| | | def downgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | op.add_column('user', sa.Column('updated_at11', mysql.INTEGER(), autoincrement=False, nullable=True)) |
| | | op.alter_column('user', 'permission', |
| | | existing_type=mysql.VARCHAR(length=16), |
| | | nullable=False, |
| | | existing_server_default=sa.text("'general'")) |
| | | op.alter_column('user', 'status', |
| | | existing_type=mysql.VARCHAR(length=10), |
| | | nullable=False, |
| | | existing_server_default=sa.text("'1'")) |
| | | op.alter_column('user', 'bisheng_id', |
| | | existing_type=mysql.INTEGER(), |
| | | nullable=False) |
| | | op.alter_column('user', 'ragflow_id', |
| | | existing_type=mysql.VARCHAR(length=32), |
| | | nullable=False) |
| | | op.create_table('user_test', |
| | | sa.Column('id', mysql.INTEGER(), autoincrement=True, nullable=False), |
| | | sa.Column('username', mysql.VARCHAR(length=255), nullable=True), |
| | | sa.Column('hashed_password', mysql.VARCHAR(length=255), nullable=True), |
| | | sa.Column('password', mysql.VARCHAR(length=255), nullable=True), |
| | | sa.Column('compellation', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('phone', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('email', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('description', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('ragflow_id', mysql.VARCHAR(length=32), nullable=True), |
| | | sa.Column('bisheng_id', mysql.INTEGER(), autoincrement=False, nullable=True), |
| | | sa.PrimaryKeyConstraint('id'), |
| | | mysql_collate='utf8mb4_0900_ai_ci', |
| | | mysql_default_charset='utf8mb4', |
| | | mysql_engine='InnoDB' |
| | | ) |
| | | op.create_index('ix_user_test_username', 'user_test', ['username'], unique=True) |
| | | op.create_index('ix_user_test_id', 'user_test', ['id'], unique=False) |
| | | # ### end Alembic commands ### |
New file |
| | |
| | | """user app update |
| | | |
| | | Revision ID: abc6bb9129ed |
| | | Revises: d4c8f204280f |
| | | Create Date: 2024-12-09 16:57:06.559644 |
| | | |
| | | """ |
| | | 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 = 'abc6bb9129ed' |
| | | down_revision: Union[str, None] = 'd4c8f204280f' |
| | | branch_labels: Union[str, Sequence[str], None] = None |
| | | depends_on: Union[str, Sequence[str], None] = None |
| | | |
| | | |
| | | def upgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | op.add_column('user_app', sa.Column('access_token', sa.String(length=1000), nullable=True)) |
| | | op.add_column('user_app', sa.Column('refresh_token', sa.String(length=1000), nullable=True)) |
| | | op.add_column('user_app', sa.Column('token_at', sa.DateTime(), nullable=True)) |
| | | op.alter_column('user_app', 'app_type', |
| | | existing_type=mysql.INTEGER(), |
| | | type_=sa.String(length=16), |
| | | existing_nullable=True) |
| | | op.drop_index('ix_user_app_username', table_name='user_app') |
| | | # ### end Alembic commands ### |
| | | |
| | | |
| | | def downgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | op.create_index('ix_user_app_username', 'user_app', ['username'], unique=True) |
| | | op.alter_column('user_app', 'app_type', |
| | | existing_type=sa.String(length=16), |
| | | type_=mysql.INTEGER(), |
| | | existing_nullable=True) |
| | | op.drop_column('user_app', 'token_at') |
| | | op.drop_column('user_app', 'refresh_token') |
| | | op.drop_column('user_app', 'access_token') |
| | | # ### end Alembic commands ### |
New file |
| | |
| | | """user app add |
| | | |
| | | Revision ID: d4c8f204280f |
| | | Revises: 07b5185945e0 |
| | | Create Date: 2024-12-09 15:43:14.470291 |
| | | |
| | | """ |
| | | 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 = 'd4c8f204280f' |
| | | down_revision: Union[str, None] = '07b5185945e0' |
| | | branch_labels: Union[str, Sequence[str], None] = None |
| | | depends_on: Union[str, Sequence[str], None] = None |
| | | |
| | | |
| | | def upgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | op.create_table('user_app', |
| | | sa.Column('id', sa.Integer(), nullable=False), |
| | | sa.Column('username', sa.String(length=255), nullable=True), |
| | | sa.Column('password', sa.String(length=255), nullable=True), |
| | | sa.Column('email', sa.String(length=255), nullable=True), |
| | | sa.Column('user_id', sa.Integer(), nullable=True), |
| | | sa.Column('app_id', sa.String(length=36), nullable=True), |
| | | sa.Column('app_type', sa.Integer(), nullable=True), |
| | | sa.Column('status', sa.String(length=10), nullable=True), |
| | | sa.Column('created_at', sa.DateTime(), nullable=True), |
| | | sa.Column('updated_at', sa.DateTime(), nullable=True), |
| | | sa.PrimaryKeyConstraint('id'), |
| | | sa.UniqueConstraint('user_id', 'app_type', name='user_app_id_ix') |
| | | ) |
| | | op.create_index(op.f('ix_user_app_id'), 'user_app', ['id'], unique=False) |
| | | op.create_index(op.f('ix_user_app_username'), 'user_app', ['username'], unique=True) |
| | | op.drop_table('dialog') |
| | | op.drop_table('flow') |
| | | # ### end Alembic commands ### |
| | | |
| | | |
| | | def downgrade() -> None: |
| | | # ### commands auto generated by Alembic - please adjust! ### |
| | | op.create_table('flow', |
| | | sa.Column('id', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('name', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('status', mysql.INTEGER(), autoincrement=False, nullable=False), |
| | | sa.PrimaryKeyConstraint('id'), |
| | | mysql_collate='utf8mb4_0900_ai_ci', |
| | | mysql_default_charset='utf8mb4', |
| | | mysql_engine='InnoDB' |
| | | ) |
| | | op.create_table('dialog', |
| | | sa.Column('id', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('name', mysql.VARCHAR(length=255), nullable=False), |
| | | sa.Column('status', mysql.VARCHAR(length=1), nullable=False), |
| | | sa.PrimaryKeyConstraint('id'), |
| | | mysql_collate='utf8mb4_0900_ai_ci', |
| | | mysql_default_charset='utf8mb4', |
| | | mysql_engine='InnoDB' |
| | | ) |
| | | op.drop_index(op.f('ix_user_app_username'), table_name='user_app') |
| | | op.drop_index(op.f('ix_user_app_id'), table_name='user_app') |
| | | op.drop_table('user_app') |
| | | # ### end Alembic commands ### |
| | |
| | | import json |
| | | import time |
| | | |
| | | from fastapi import APIRouter, Depends |
| | | from sqlalchemy.orm import Session |
| | |
| | | from app.models.token_model import upsert_token, get_token, update_token |
| | | from app.models.user import UserCreate, LoginData |
| | | from app.models.user_model import UserModel |
| | | from app.service.auth import authenticate_user, create_access_token |
| | | from app.service.auth import authenticate_user, create_access_token, is_valid_password, save_register_user, \ |
| | | update_user_token, UserAppDao |
| | | from app.service.bisheng import BishengService |
| | | from app.service.common.app_register import AppRegisterDao |
| | | from app.service.difyService import DifyService |
| | | from app.service.ragflow import RagflowService |
| | | from sqlalchemy.future import select |
| | | |
| | |
| | | |
| | | |
| | | @router.post("/v2/login", response_model=Response) |
| | | async def login_test(login_data: LoginData, db: Session = Depends(get_db), pdb: AsyncSession = Depends(get_pdb)): |
| | | async def login_v2(login_data: LoginData, db: Session = Depends(get_db), pdb: AsyncSession = Depends(get_pdb)): |
| | | user = authenticate_user(db, login_data.username, login_data.password) |
| | | if not user: |
| | | return Response(code=400, msg="Incorrect username or password") |
| | |
| | | logger.error("未知注册应用---") |
| | | continue |
| | | try: |
| | | token = await service.login(login_data.username, login_data.password) |
| | | user_app = UserAppDao(db).get_data_by_id(user.id, app["id"]) |
| | | if user_app: |
| | | name = user_app.username |
| | | token = await service.login(name, login_data.password) |
| | | token_dict[app["id"]] = token |
| | | except Exception as e: |
| | | return Response(code=500, msg=f"Failed to login with {app['id']}: {str(e)}") |
| | |
| | | access_token = create_access_token(data={"sub": user.username, "user_id": user.id}) |
| | | |
| | | await update_token(db, user.id, access_token, token_dict) |
| | | await update_user_token(db, user.id, token_dict) |
| | | result = await pdb.execute(select(AppToken).where(AppToken.id == user.id)) |
| | | db_app_token = result.scalars().first() |
| | | if isinstance(access_token, bytes): |
| | |
| | | |
| | | |
| | | @router.post("/v2/register", response_model=Response) |
| | | async def register_test(user: UserCreate, db=Depends(get_db)): |
| | | async def register_v2(user: UserCreate, db=Depends(get_db)): |
| | | if not is_valid_password(user.password): |
| | | return Response(code=400, msg="The password must be at least 8 and contain both numbers and letters") |
| | | db_user = db.query(UserModel).filter(UserModel.username == user.username).first() |
| | | if db_user: |
| | | return Response(code=200, msg="Username already registered") |
| | |
| | | elif app["id"] == BISHENG: |
| | | service = BishengService(settings.sgb_base_url) |
| | | elif app["id"] == DIFY: |
| | | continue |
| | | service = DifyService(settings.dify_base_url) |
| | | else: |
| | | logger.error("未知注册应用---") |
| | | continue |
| | | try: |
| | | register_info = await service.register(user.username, user.password) |
| | | register_dict[app['id']] = register_info.get("id") if app['id'] == RAGFLOW else register_info.get("user_id") if app['id'] == BISHENG else "" |
| | | name = app["id"] + str(int(time.time())) |
| | | register_info = await service.register(name, user.password) |
| | | print(register_info) |
| | | register_dict[app['id']] = {"id":register_info.get("id"), "name": name, "email": register_info.get("email")} |
| | | except Exception as e: |
| | | return Response(code=500, msg=f"Failed to register with {app['id']}: {str(e)}") |
| | | |
| | | # 存储用户信息 |
| | | hashed_password = pwd_context.hash(user.password) |
| | | db_user = UserModel(username=user.username, hashed_password=hashed_password, email=user.email) |
| | | db_user.password = db_user.encrypted_password(user.password) |
| | | for k, v in register_dict.items(): |
| | | setattr(db_user, k.replace("app", "id"), v) |
| | | db.add(db_user) |
| | | db.commit() |
| | | db.refresh(db_user) |
| | | return Response(code=200, msg="User registered successfully",data={"username": db_user.username}) |
| | | # hashed_password = pwd_context.hash(user.password) |
| | | # db_user = UserModel(username=user.username, hashed_password=hashed_password, email=user.email) |
| | | # db_user.password = db_user.encrypted_password(user.password) |
| | | # for k, v in register_dict.items(): |
| | | # setattr(db_user, k.replace("app", "id"), v) |
| | | # db.add(db_user) |
| | | # db.commit() |
| | | # db.refresh(db_user) |
| | | |
| | | is_sava = await save_register_user(db, user.username, user.password, user.email, register_dict) |
| | | if not is_sava: |
| | | return Response(code=500, msg=f"Failed to register with app") |
| | | return Response(code=200, msg="User registered successfully",data={"username": user.username}) |
| | |
| | | ### -----------app register -------------- |
| | | RAGFLOW = "ragflow_app" |
| | | BISHENG = "bisheng_app" |
| | | DIFY = "dify_app" |
| | | DIFY = "dify_app" |
| | | |
| | | ### ---------------app type----------------- |
| | | BASIC_ID = 3 |
| | | RAGFLOW_ID = 1 |
| | | BISHENG_ID = 2 |
| | | DIFY_ID = 4 |
| | |
| | | from .resource_model import * |
| | | from .role_model import * |
| | | from .user_model import * |
| | | from .token_model import * |
| | | from .session_model import SessionModel |
| | | from .public_api_model import * |
| | | |
| | | |
| | | # 获取当前时区的时间 |
| | |
| | | import json |
| | | from datetime import datetime |
| | | from enum import IntEnum |
| | | |
| | | import pytz |
| | | from sqlalchemy import Column, String, Enum as SQLAlchemyEnum, Integer, DateTime, JSON, TEXT |
| | | |
| | | from app.models import AgentType, current_time |
| | | from app.models.agent_model import AgentType |
| | | # from app.models import current_time |
| | | from app.models.base_model import Base |
| | | |
| | | def current_time(): |
| | | tz = pytz.timezone('Asia/Shanghai') |
| | | return datetime.now(tz) |
| | | |
| | | class SessionModel(Base): |
| | | __tablename__ = "sessions" |
| | |
| | | from datetime import datetime |
| | | |
| | | from cryptography.fernet import Fernet |
| | | from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime |
| | | from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime, UniqueConstraint |
| | | from sqlalchemy.orm import relationship, backref |
| | | |
| | | from app.config.config import settings |
| | |
| | | username = Column(String(255), unique=True, index=True) |
| | | hashed_password = Column(String(255)) |
| | | password = Column(String(255)) |
| | | compellation = Column(String(255), nullable=False, default="") |
| | | phone = Column(String(255), nullable=False, default="") |
| | | email = Column(String(255), nullable=False, default="") |
| | | description = Column(String(255), nullable=False, default="") |
| | | compellation = Column(String(255), default="") |
| | | phone = Column(String(255), default="") |
| | | email = Column(String(255), default="") |
| | | description = Column(String(255), default="") |
| | | ragflow_id = Column(String(32)) |
| | | bisheng_id = Column(Integer) |
| | | login_name = Column(String(100)) |
| | | status = Column(String(10), nullable=False, default="1") |
| | | status = Column(String(10), default="1") |
| | | creator = Column(String(36)) |
| | | sex = Column(String(1)) |
| | | permission = Column(String(16), nullable=False, default="general") |
| | | permission = Column(String(16), default="general") |
| | | age = Column(Integer) |
| | | created_at = Column(DateTime, default=datetime.now()) |
| | | updated_at = Column(DateTime, default=datetime.now(), onupdate=datetime.now()) |
| | | updated_at11 = Column(Integer) |
| | | |
| | | |
| | | |
| | |
| | | |
| | | |
| | | |
| | | class UserModel(Base): |
| | | __tablename__ = "user_test" |
| | | class UserAppModel(Base): |
| | | __tablename__ = "user_app" |
| | | __table_args__ = (UniqueConstraint('user_id', 'app_type', name='user_app_id_ix'),) |
| | | id = Column(Integer, primary_key=True, index=True) |
| | | username = Column(String(255), unique=True, index=True) |
| | | hashed_password = Column(String(255)) |
| | | username = Column(String(255)) |
| | | password = Column(String(255)) |
| | | compellation = Column(String(255), nullable=False, default="") |
| | | phone = Column(String(255), nullable=False, default="") |
| | | email = Column(String(255), nullable=False, default="") |
| | | description = Column(String(255), nullable=False, default="") |
| | | ragflow_id = Column(String(32)) |
| | | bisheng_id = Column(Integer) |
| | | email = Column(String(255), default="") |
| | | user_id = Column(Integer) |
| | | app_id = Column(String(36)) |
| | | app_type = Column(String(16)) |
| | | status = Column(String(10), default="1") |
| | | access_token = Column(String(1000)) |
| | | refresh_token = Column(String(1000)) |
| | | token_at = Column(DateTime, default=datetime.now()) |
| | | created_at = Column(DateTime, default=datetime.now()) |
| | | updated_at = Column(DateTime, default=datetime.now(), onupdate=datetime.now()) |
| | | |
| | | def to_json(self): |
| | | return { |
| | | 'id': self.id, |
| | | 'userName': self.username, |
| | | 'createTime': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else "", |
| | | 'updateTime': self.updated_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else "", |
| | | 'password': self.password, |
| | | 'email': self.email, |
| | | 'user_id': self.user_id, |
| | | 'app_id': self.app_id, |
| | | "app_type": self.app_type, |
| | | 'status': self.status, |
| | | } |
| | |
| | | import re |
| | | from datetime import datetime, timedelta |
| | | from typing import Type |
| | | |
| | | from jwt import encode, decode, exceptions |
| | | from passlib.context import CryptContext |
| | | from fastapi import HTTPException, status |
| | | from sqlalchemy.orm import Session |
| | | |
| | | from Log import logger |
| | | from app.config.config import settings |
| | | from app.models.user_model import UserModel |
| | | from app.models.user_model import UserModel, UserAppModel |
| | | |
| | | SECRET_KEY = settings.secret_key |
| | | ALGORITHM = "HS256" |
| | |
| | | return payload |
| | | except exceptions.DecodeError: |
| | | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials") |
| | | |
| | | |
| | | def is_valid_password(password: str) -> bool: |
| | | if len(password) <= 8: |
| | | return False |
| | | has_digit = re.search(r'[0-9]', password) |
| | | has_letter = re.search(r'[A-Za-z]', password) |
| | | |
| | | # 如果密码包含数字和字母,则返回True,否则返回None |
| | | return has_digit is not None and has_letter is not None |
| | | |
| | | |
| | | async def save_register_user(db, username, password, email, register_dict): |
| | | user_id = "" |
| | | try: |
| | | hashed_password = pwd_context.hash(password) |
| | | db_user = UserModel(username=username, hashed_password=hashed_password, email=email) |
| | | pwd = db_user.encrypted_password(password) |
| | | db_user.password = pwd |
| | | db.add(db_user) |
| | | db.add(db_user) |
| | | db.commit() |
| | | db.refresh(db_user) |
| | | user_id = db_user.id |
| | | for k, v in register_dict.items(): |
| | | UserAppDao(db).update_and_insert_token(v.get("name"), pwd, v.get("email"), user_id, str(v.get("id")), k) |
| | | |
| | | except Exception as e: |
| | | logger.error(e) |
| | | # db.roolback() |
| | | if user_id: |
| | | db.query(UserModel).filter(UserModel.id == user_id).delete() |
| | | return False |
| | | return True |
| | | |
| | | |
| | | async def update_user_token(db, user_id, token_dict): |
| | | |
| | | try: |
| | | for k, v in token_dict.items(): |
| | | UserAppDao(db).update_user_app_data({"user_id": user_id, "app_type": k}, |
| | | {"access_token": v, "token_at": datetime.now()}) |
| | | |
| | | except Exception as e: |
| | | logger.error(e) |
| | | return False |
| | | return True |
| | | |
| | | |
| | | class UserAppDao: |
| | | def __init__(self, db: Session): |
| | | self.db = db |
| | | |
| | | def get_data_by_id(self, user_id: int, app_type: int) -> Type[UserAppModel] | None: |
| | | session = self.db.query(UserAppModel).filter_by(user_id=user_id, app_type=app_type).first() |
| | | return session |
| | | |
| | | def update_user_app_data(self, query: int, update_data: str): |
| | | |
| | | logger.error("更新数据df update_app_data---------------------------") |
| | | try: |
| | | self.db.query(UserAppModel).filter_by(**query).update(update_data) |
| | | self.db.commit() |
| | | except Exception as e: |
| | | logger.error(e) |
| | | self.db.rollback() |
| | | raise Exception("更新失败!") |
| | | |
| | | def insert_user_app_data(self, username: str, password: str, email: str, user_id: int, app_id: str, app_type: int): |
| | | logger.error("新增数据df insert_user_app_data---------------------------") |
| | | new_session = UserAppModel( |
| | | username=username, |
| | | password=password, |
| | | email=email, |
| | | user_id=user_id, |
| | | app_id=app_id, |
| | | app_type=app_type, |
| | | ) |
| | | self.db.add(new_session) |
| | | self.db.commit() |
| | | self.db.refresh(new_session) |
| | | return new_session |
| | | |
| | | def update_and_insert_token(self, username: str, password: str, email: str, user_id: int, app_id: str, |
| | | app_type: int): |
| | | |
| | | logger.error("更新或者添加数据 update_and_insert_token---------------------------") |
| | | token_boj = self.get_data_by_id(user_id, app_type) |
| | | if token_boj: |
| | | self.update_user_app_data({"id": token_boj.id}, {"username": username, |
| | | "password": password, "email": email, "username": username, |
| | | "updated_at": datetime.now(), |
| | | }) |
| | | else: |
| | | self.insert_user_app_data(username, password, email, user_id, app_id, app_type) |
| | |
| | | json={"user_name": username, "password": password}, |
| | | headers={'Content-Type': 'application/json'} |
| | | ) |
| | | return self._check_response(response) |
| | | res = self._check_response(response) |
| | | if isinstance(res, dict): |
| | | res["id"] = res.get("user_id") |
| | | return res |
| | | |
| | | async def login(self, username: str, password: str) -> str: |
| | | public_key = await self.get_public_key_api() |
| | |
| | | import json |
| | | from datetime import datetime |
| | | from urllib.parse import urlparse, parse_qs |
| | | |
| | | import httpx |
| | | from typing import Union, Dict, List |
| | | from fastapi import HTTPException |
| | | from starlette import status |
| | | |
| | | # from Log import logger |
| | | from app.config.config import settings |
| | | from app.utils.rsa_crypto import RagflowCrypto |
| | | |
| | |
| | | else: |
| | | return data |
| | | |
| | | async def register(self, username: str, password: str): |
| | | password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password) |
| | | async def register(self, username: str, password: str, token=None): |
| | | if not token: |
| | | token = await get_df_token() |
| | | email = f"{username}@df.com" |
| | | invite_res = await self.invite_workspaces_member(token, [email], "admin") |
| | | # print(invite_res) |
| | | if invite_res.get("result") != "success" or not invite_res.get("invitation_results"): |
| | | # logger.error(invite_res) |
| | | return {} |
| | | invite_token = \ |
| | | parse_qs(urlparse(invite_res.get("invitation_results")[0].get("url", "")).query).get('token', [None])[0] |
| | | # print(invite_token) |
| | | if not invite_token: |
| | | return {} |
| | | await self.login(email, password, True, invite_token) |
| | | activate_res = await self.activate(email, username, invite_token, "", "") |
| | | activate_res["email"] = email |
| | | activate_res["id"] = invite_token |
| | | return activate_res |
| | | |
| | | |
| | | async def invite_workspaces_member(self, token, emails: list, role: str): |
| | | async with httpx.AsyncClient() as client: |
| | | response = await client.post( |
| | | f"{self.base_url}/v1/user/register", |
| | | headers={'Content-Type': 'application/json'}, |
| | | json={"nickname": username, "email": f"{username}@example.com", "password": password} |
| | | f"{self.base_url}/console/api/workspaces/current/members/invite-email", |
| | | headers={'Content-Type': 'application/json',"Authorization": f'Bearer {token}'}, |
| | | json={"emails": emails, "language": "zh-Hans", "role": role} |
| | | ) |
| | | if response.status_code != 200: |
| | | raise Exception(f"Ragflow registration failed: {response.text}") |
| | | print(response.text) |
| | | return self._handle_response(response) |
| | | |
| | | async def login(self, username: str, password: str) -> str: |
| | | password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password) |
| | | async def login(self, email: str, password: str, remember_me,invite_token:str="") -> str: |
| | | # password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password) |
| | | data = {"email": email, "password": password, "remember_me": remember_me, "invite_token": invite_token, |
| | | "language": "zh-Hans"} |
| | | |
| | | async with httpx.AsyncClient() as client: |
| | | response = await client.post( |
| | | f"{self.base_url}/v1/user/login", |
| | | f"{self.base_url}/console/api/login", |
| | | headers={'Content-Type': 'application/json'}, |
| | | json={"email": f"{username}@example.com", "password": password} |
| | | json=data |
| | | ) |
| | | if response.status_code != 200: |
| | | raise Exception(f"Ragflow login failed: {response.text}") |
| | | authorization = response.headers.get('Authorization') |
| | | if not authorization: |
| | | raise Exception("Authorization header not found in response") |
| | | return authorization |
| | | raise Exception(f"df login failed: {response.text}") |
| | | return self._handle_response(response) |
| | | |
| | | async def email_check(self, token, email: str): |
| | | async with httpx.AsyncClient() as client: |
| | | response = await client.get( |
| | | f"{self.base_url}/console/api/activate/check?email={email}&token={token}", |
| | | headers={'Content-Type': 'application/json'} |
| | | ) |
| | | return self._handle_response(response) |
| | | |
| | | async def activate(self, email: str, name: str, token, workspace_id:str, access_token) -> str: |
| | | # password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password) |
| | | data = {"email": email, "name": name, "token": token, # "workspace_id": workspace_id, |
| | | "interface_language": "en-US", "timezone": "Asia/Shanghai"} |
| | | print(data) |
| | | async with httpx.AsyncClient() as client: |
| | | response = await client.post( |
| | | f"{self.base_url}/console/api/activate", |
| | | headers={'Content-Type': 'application/json'}, # , 'Authorization': f'Bearer {access_token}' |
| | | json=data |
| | | ) |
| | | if response.status_code != 200: |
| | | raise Exception(f"df login failed: {response.text}") |
| | | return self._handle_response(response) |
| | | |
| | | async def invite_member_activate(self, token:str, email: str, name: str, password:str) -> str: |
| | | invite_res = await self.invite_workspaces_member(token, [email], "admin") |
| | | print(invite_res) |
| | | if invite_res.get("result") != "success" or not invite_res.get("invitation_results"): |
| | | # logger.error(invite_res) |
| | | return {} |
| | | invite_token = parse_qs(urlparse(invite_res.get("invitation_results")[0].get("url", "")).query).get('token', [None])[0] |
| | | # print(invite_token) |
| | | if not invite_token: |
| | | return {} |
| | | await self.login(email, password, True, invite_token) |
| | | activate_res = await self.activate(email, name,invite_token, "", "") |
| | | return activate_res |
| | | |
| | | |
| | | |
| | | async def chat(self, token: str, user_id: int, message: str, upload_file_id: str, conversation_id: str): |
| | | |
| | |
| | | if __name__ == "__main__": |
| | | async def a(): |
| | | a = DifyService("http://192.168.20.116") |
| | | b = await a.get_session_history("app-YmOAMDsPpDDlqryMHnc9TzTO", "f94c6328-8ff0-4713-af3f-e823d547682d", |
| | | "63") |
| | | # b = await a.invite_workspaces_member("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMjE0Y2I2ODctZTZlMC00ZTE2LWExNzUtYzcyNDNlMGRhMWEwIiwiZXhwIjoxNzMzNzI2NDA5LCJpc3MiOiJTRUxGX0hPU1RFRCIsInN1YiI6IkNvbnNvbGUgQVBJIFBhc3Nwb3J0In0.jLe1ODbcqCe79CDt6fFwnuuQL4I2FB9YTs9ynk4FeoQ", ["test05@163.com"], |
| | | # "admin") |
| | | |
| | | # b = await a.email_check( |
| | | # "ebd36739-0272-4b3f-95ab-0c6ac1639831", |
| | | # "test05@163.com") |
| | | # b = await a.login( |
| | | # "test05@163.com", |
| | | # "zhaoqg123456", |
| | | # True, "ebd36739-0272-4b3f-95ab-0c6ac1639831") |
| | | |
| | | |
| | | |
| | | # b = await a.activate( |
| | | # "test05@163.com", |
| | | # "test05", "ebd36739-0272-4b3f-95ab-0c6ac1639831", "", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiNzg5OWUzOGQtNzczOS00NGNmLTgyODItZmFlMGZhNDJlZDYwIiwiZXhwIjoxNzMzNzI5NjQyLCJpc3MiOiJTRUxGX0hPU1RFRCIsInN1YiI6IkNvbnNvbGUgQVBJIFBhc3Nwb3J0In0.YMvypPnrvvUIfqzcESj820nP46IsFdTpF_YPz8_Exso") |
| | | |
| | | b = await a.invite_member_activate( |
| | | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMDE2NTcxNjAtZTllYi00NzVhLWIzMzYtZjlmZWJlY2I5YjczIiwiZXhwIjoxNzMzNzM0ODE0LCJpc3MiOiJTRUxGX0hPU1RFRCIsInN1YiI6IkNvbnNvbGUgQVBJIFBhc3Nwb3J0In0.khaXX3ndDe_pccEHcyTUcO2sgBCEfXCR74ZniP_b54Y", |
| | | "zhao1@df.com", |
| | | "zhao1Q", |
| | | "ZHAOQG123456") |
| | | print(b) |
| | | |
| | | import asyncio |
| | |
| | | ('basic_excel_talk', 6, '智能数据', 'BASIC', 'excelTalk'), |
| | | ('basic_question_talk', 7, '出题组卷', 'BASIC', 'questionTalk'), |
| | | ('9d75142a-66eb-4e23-b7d4-03efe4584915', 8, '小数绘图', 'DIFY', 'imageTalk'), |
| | | ('basic_paper_talk', 8, '文档出卷', 'BASIC', 'paperTalk') |
| | | ('basic_paper_talk', 8, '文档出卷', 'BASIC', 'paperTalk'), |
| | | ('basic_report_clean', 10, '文档报告', 'DIFY', 'reportWorkflow') |
| | | ] |
| | | |
| | | for agent in initial_agents: |
| | |
| | | # 在应用关闭时执行清理操作(如果需要) |
| | | pass |
| | | |
| | | init_db() |
| | | # init_db() |
| | | app = FastAPI( |
| | | title="basic_rag_gateway", |
| | | version="0.1", |