Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion #6

Closed
nsankar90 opened this issue Jan 22, 2022 · 6 comments
Closed

Suggestion #6

nsankar90 opened this issue Jan 22, 2022 · 6 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@nsankar90
Copy link

Is it possible to write out all the routers into a python file?
Which would be great while we add more end points for the tags

@LuisLuii
Copy link
Owner

LuisLuii commented Jan 23, 2022

Hi nsankar90, thanks for your suggestion, I have the same plan to build a code gen, but I have no relevant development experience, so it is still in the POC stage. Do you have any implementation suggestions? :)

@LuisLuii
Copy link
Owner

And you can add a new end point for the tags by tags parameter

from fastapi import FastAPI
from sqlalchemy import *
from sqlalchemy.orm import *
from fastapi_quickcrud.crud_router import generic_sql_crud_router_builder

Base = declarative_base()
class Parent(Base):
    __tablename__ = 'parent_o2o'
    id = Column(Integer, primary_key=True, comment='test-test-test')
    name = Column(String, default='ok', unique = True)
    children = relationship("Child", back_populates="parent")



class Child(Base):
    __tablename__ = 'child_o2o'
    id = Column(Integer, primary_key=True, comment='child_pk_test')
    parent_id = Column(Integer, ForeignKey('parent_o2o.id'), info=({'description': 'child_parent_id_test'}))
    parent = relationship("Parent", back_populates="children")


crud_route_parent = generic_sql_crud_router_builder(
    db_model=Parent,
    prefix="/parent",
    tags=["parent"],
)

crud_route_child = generic_sql_crud_router_builder(
    db_model=Child,
    prefix="/child",
    tags=["child"]
)

app = FastAPI()
[app.include_router(i) for i in [crud_route_parent, crud_route_child]]

@app.get("/", tags=["child"])
async def root():
    return {"message": "Hello World"}

import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000, debug=False)

@LuisLuii
Copy link
Owner

LuisLuii commented Jan 23, 2022

Is it possible to write out all the routers into a python file?
About this question I may take some time to investigate, since I have also need to convert pedantic model / data classes model to code.
Also welcome you PR

In this time, you can use sqlalchemy_to_pydantic() to generate the predefine pedantic model to build you api
sqlalchemy_to_pydantic will generate the predesign pydantic model to build the API, you can also use it to build you custom API.

import uvicorn
from fastapi import FastAPI, Depends
from sqlalchemy.orm import declarative_base, sessionmaker

from fastapi_quickcrud import CrudMethods
from fastapi_quickcrud import crud_router_builder
from fastapi_quickcrud import sqlalchemy_to_pydantic
from fastapi_quickcrud.misc.memory_sql import sync_memory_db

app = FastAPI()

Base = declarative_base()
metadata = Base.metadata

from sqlalchemy import CHAR, Column, ForeignKey, Integer, Table
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
metadata = Base.metadata
association_table = Table('association', Base.metadata,
                          Column('left_id', ForeignKey('left.id')),
                          Column('right_id', ForeignKey('right.id'))
                          )


class Parent(Base):
    __tablename__ = 'left'
    id = Column(Integer, primary_key=True)
    children = relationship("Child",
                            secondary=association_table)


class Child(Base):
    __tablename__ = 'right'
    id = Column(Integer, primary_key=True)
    name = Column(CHAR, nullable=True)


user_model_m2m = sqlalchemy_to_pydantic(db_model=association_table,
                                        crud_methods=[
                                            CrudMethods.FIND_MANY,
                                            CrudMethods.UPSERT_ONE,
                                            CrudMethods.UPDATE_MANY,
                                            CrudMethods.DELETE_MANY,
                                            CrudMethods.PATCH_MANY,

                                        ],
                                        exclude_columns=[])

user_model_set = sqlalchemy_to_pydantic(db_model=Parent,
                                        crud_methods=[
                                            CrudMethods.FIND_MANY,
                                            CrudMethods.FIND_ONE,
                                            CrudMethods.CREATE_ONE,
                                            CrudMethods.UPDATE_MANY,
                                            CrudMethods.UPDATE_ONE,
                                            CrudMethods.DELETE_ONE,
                                            CrudMethods.DELETE_MANY,
                                            CrudMethods.PATCH_MANY,

                                        ],
                                        exclude_columns=[])

friend_model_set = sqlalchemy_to_pydantic(db_model=Child,
                                          crud_methods=[
                                              CrudMethods.FIND_MANY,
                                              CrudMethods.UPSERT_MANY,
                                              CrudMethods.UPDATE_MANY,
                                              CrudMethods.DELETE_MANY,
                                              CrudMethods.CREATE_ONE,
                                              CrudMethods.PATCH_MANY,

                                          ],
                                          exclude_columns=[])

crud_route_1 = crud_router_builder(crud_models=user_model_set,
                                   db_model=Parent,
                                   prefix="/Parent",
                                   dependencies=[],
                                   async_mode=True,
                                   tags=["Parent"]
                                   )
crud_route_3 = crud_router_builder(crud_models=user_model_m2m,
                                   db_model=association_table,
                                   prefix="/Parent2child",
                                   dependencies=[],
                                   async_mode=True,
                                   tags=["m2m"]
                                   )
crud_route_2 = crud_router_builder(crud_models=friend_model_set,
                                   db_model=Child,
                                   async_mode=True,
                                   prefix="/Child",
                                   dependencies=[],
                                   tags=["Child"]
                                   )
post_model = friend_model_set.POST[CrudMethods.CREATE_ONE]

sync_memory_db.create_memory_table(Child)
@app.post("/hello",
           status_code=201,
          tags=["Child"],
           response_model=post_model.responseModel,
           dependencies=[])
async def my_api(
        body: post_model.requestBodyModel = Depends(post_model.requestBodyModel),
        session=Depends(sync_memory_db.get_memory_db_session)
):
    db_item = Child(** body.__dict__)
    session.add(db_item)
    session.commit()
    session.refresh(db_item)
    return db_item.__dict__


app.include_router(crud_route_1)
app.include_router(crud_route_2)
app.include_router(crud_route_3)
uvicorn.run(app, host="0.0.0.0", port=8000, debug=False)

@nsankar90
Copy link
Author

nsankar90 commented Jan 23, 2022

Thanks for the quick reply LuisLuii

I tried this sqlalchemy_to_pydantic but I thought that was still in experimental stage.
As far as prototyping that is am very much OK with this but I need some additional validation and customisation on each end points, which could not be generalised across endpoints.

I am also working on generating codes so that we could make some quick customisation to land on a desired outcome and consume less memory.

Will update here once I have anything solid.

Thanks again for the time saving repo

@LuisLuii LuisLuii added enhancement New feature or request documentation Improvements or additions to documentation labels Feb 7, 2022
@LuisLuii
Copy link
Owner

LuisLuii commented Mar 7, 2022

I am started for this feature and this issue will be closed, let we discuss in #11

@LuisLuii
Copy link
Owner

LuisLuii commented Nov 1, 2022

try it LoL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants