sparckles / Robyn

Robyn is a Super Fast Async Python Web Framework with a Rust runtime.
https://robyn.tech/
BSD 2-Clause "Simplified" License
3.9k stars 195 forks source link

Fastapi To Robyn #821

Open Xingsandesu opened 1 month ago

Xingsandesu commented 1 month ago

I want to migrate my fastapi application to robyn. I read the documentation of robyn. Its usage is indeed very similar to fastapi, but it does not support pydantic. I think it would be better if robyn could support pydantic for data verification, so that my fastapi application can basically be seamlessly migrated to robyn. Secondly, I am still concerned about whether robyn can fully support sqlalchemy's async connection. I read the official document and the example above uses synchronous pymysql, not asynchronous aiomysql. I really like this project, thank you for your efforts

sansyrox commented 1 month ago

Hey @Xingsandesu πŸ‘‹

Thank you for opening the issue πŸ˜„ .

I think it would be better if robyn could support pydantic for data verification, so that my fastapi application can basically be seamlessly migrated to robyn.

This is a top priority issue for us! It will be definitely implemented within the next few weeks πŸ˜„

Secondly, I am still concerned about whether robyn can fully support sqlalchemy's async connection. I read the official document and the example above uses synchronous pymysql, not asynchronous aiomysql.

Robyn supports all sorts of async tasks. But if you have something in mind that you'd like to clarify, I would be happy to have a look

Xingsandesu commented 1 month ago

Robyn supports all sorts of async tasks. But if you have something in mind that you'd like to clarify, I would be happy to have a look

thank you very much for your workπŸ˜„. This is part of my database code.This example uses sqlalchemy.ext.asyncio and aiomysql to implement an asynchronous database session, and uses the fastapi dependency to use an asynchronous database session. This will prevent various database operations from forming performance bottlenecks due to the bottleneck of pymysql. I think I should be able to use a similar method if I migrate from fastapi to Robyn. Thank you very much for your work. When pydantic is supported, I will cooperate with you to test this version as soon as possible if possible.

setting.py

....
DATABASE_URL = f"mysql+aiomysql://{DATABASES['USER']}:{DATABASES['PASSWORD']}@{DATABASES['HOST']}:{DATABASES['PORT']}/{DATABASES['NAME']}"
....

models.py

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base
from settings import DATABASE_URL, DATABASE_ENGINE_ECHO, DATABASE_ENGINE_POOL_SIZE, DATABASE_ENGINE_MAX_OVERFLOW, DATABASE_ENGINE_POOL_TIMEOUT, DATABASE_SESSION_EXPIRE_ON_COMMIT

engine = create_async_engine(
    DATABASE_URL, 
    echo=DATABASE_ENGINE_ECHO, 
    pool_size=DATABASE_ENGINE_POOL_SIZE, 
    max_overflow=DATABASE_ENGINE_MAX_OVERFLOW, 
    pool_timeout=DATABASE_ENGINE_POOL_TIMEOUT
)

SessionLocal = sessionmaker(
    engine, 
    expire_on_commit=DATABASE_SESSION_EXPIRE_ON_COMMIT, 
    class_=AsyncSession
)

Base = declarative_base()

async def get_db():
    session = SessionLocal()
    try:
        yield session
    except Exception as e:
        logger.error(f"error::{str(e)}")
    finally:
        await session.close()

...

view.py

...
async def add_user(user: UserCreate, db: AsyncSession = Depends(get_db)):
    if await record_exists(db, "users", {"userName": user.userName}):
        raise HTTPException(status_code=400, detail="User name already exists")
    else:
        db_user = User(**user.model_dump())
        db.add(db_user)
        await db.commit()
        await db.refresh(db_user)
        return db_user
...