Giter Site home page Giter Site logo

grillazz / fastapi-sqlalchemy-asyncpg Goto Github PK

View Code? Open in Web Editor NEW
338.0 8.0 47.0 7.36 MB

Integration of FastAPI framework supported by Pydantic with SQLAlchemy ORM and PostgreSQL on asyncpg driver

License: MIT License

Dockerfile 2.80% Makefile 4.30% Python 92.15% Mako 0.76%
fastapi sqlalchemy postgresql asyncpg python python3 docker fastapi-sqlalchemy asyncio pydantic

fastapi-sqlalchemy-asyncpg's Introduction

fastapi-sqlalchemy-asyncpg

Contributors Forks Stargazers Issues MIT License LinkedIn

fastapi-sqlalchemy-asyncpg

Table of Contents
  1. About The Project
  2. Getting Started
  3. Acknowledgments

About The Project

Example of FastAPI integration supported by almighty Pydantic 2.0 with SQLAlchemy ORM and PostgreSQL16 connected via fastest Database Client Library for python/asyncio asyncpg.

Beside of using latest and greatest version of SQLAlchemy with it robustness, powerfulness and speed of asyncpg there is FastAPI (modern, fast (high-performance), web framework for building APIs with Python 3.8+ based on standard Python type hints.) already reviewed on thoughtworks and noted in Python Developers Survey 2021 Results as the fifth official annual Python Developers Survey, conducted as a collaborative effort between the Python Software Foundation and JetBrains.

Built With

FastAPI Pydantic SQLAlchemy Uvicorn pytest asyncpg alembic rich

(back to top)

Getting Started

Make will help you

To build , run and test and more ... use magic of make help to play with this project.

1. make docker-build
2. make docker-up
3. make docker-apply-db-migrations
4. make docker-feed-db

(back to top)

How to feed database

It took me a while to find nice data set. Hope works of Shakespeare as example will be able to cover first part with read only declarative base configuration and all type of funny selects :) Data set is coming form https://github.com/catherinedevlin/opensourceshakespeare Next models were generated with https://github.com/agronholm/sqlacodegen

(back to top)

Rainbow logs with rich 🌈

To deliver better user(developer) experience when watching logs with tons of information from few emitters (which are really needy on development stage) project is using rich library. Event with rich superpowers reading logs is not easy. Found rich really nice - but it took time to learn how to integrate it as logger object properly and keep it as singleton.

To address below needs:

  • it is hard to find what I am looking for even with glasses on.
  • don’t want to hire ELK to be able to use logs.
  • want to move fast enough with debugging.

Below steps were done to integrate rich into project.

  1. Configure emitters with config.ini
  2. Eliminate duplicates i.e. sqlalchemy echo by separate handlers
  3. Keep logger as singleton pattern to avoid multiple instances
  4. add uvicorn parameter --log-config config.ini

sample-logs-with-rich

(back to top)

Setup User Auth

Setup user authentication with JWT and Redis as token storage.

Local development with poetry

pyenv install 3.12 && pyenv local 3.12
poetry install

Hope you enjoy it.

Import xlsx files with polars and calamine

Power of Polars Library in data manipulation and analysis. It uses the polars library to read the Excel data into a DataFrame by passing the bytes to the pl.read_excel() function - https://docs.pola.rs/py-polars/html/reference/api/polars.read_excel.html In pl.read_excel() β€œcalamine” engine can be used for reading all major types of Excel Workbook (.xlsx, .xlsb, .xls) and is dramatically faster than the other options, using the fastexcel module to bind calamine.

(back to top)

Acknowledgments

Use this space to list resources you find helpful and would like to give credit to. I've included a few of my favorites to kick things off!

(back to top)

Change Log

  • [long time ago...] it was a long time ago in galaxy far far away...
  • [JUN 4 2022] alembic migrations added to project
  • [JUN 6 2022] initial dataset for shakespeare models
  • [OCT 3 2022] poetry added to project
  • [NOV 12 2022] ruff implemented to project as linting tool
  • [FEB 14 2023] bump project to Python 3.11
  • [APR 10 2023] implement logging with rich
  • [APR 28 2023] Rainbow logs with rich 🌈
  • [JUL 7 2023] migrate to pydantic 2.0 ⏩
  • [JUL 25 2023] add user authentication with JWT and Redis as token storage πŸ”’ πŸ”‘
  • [SEP 2 2023] add passlib and bcrypt for password hashing πŸ”’ πŸ”‘
  • [OCT 21 2023] refactor shakespeare models to use sqlalchemy 2.0 ⏩
  • [FEB 1 2024] bump project to Python 3.12 ⏩
  • [MAR 15 2024] add polars and calamine to project 😻

(back to top)

fastapi-sqlalchemy-asyncpg's People

Contributors

grillazz avatar levinotik avatar snyk-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastapi-sqlalchemy-asyncpg's Issues

Unnecessary method

Hey grillazz! Thanks for this awesome repo :)

Does this method have any purpose? It does not seem to be referenced anywhere.

async def get_async_db() -> AsyncGenerator:
try:
session: AsyncSession = AsyncSessionFactory()
logger.debug(f"ASYNC Pool: {engine.pool.status()}")
yield session
except SQLAlchemyError as sql_ex:
await session.rollback()
raise sql_ex
except HTTPException as http_ex:
await session.rollback()
raise http_ex
else:
await session.commit()
finally:
await session.close()

SQLAlchemy Engine disposal

I've come across your project and I really appreciate what you've done.
I have a question that bugs me for a long time and I've never seen any project addressing it, including yours.

When you create an AsyncEngine, you are supposed to dispose it, ideally in shutdown event. However, I never see anyone doing it in practice. Is it because you rely on GC of Python to clean it for you?

Discuss about config.py

import os
from functools import lru_cache

from pydantic import PostgresDsn, RedisDsn
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    asyncpg_url: PostgresDsn = os.getenv("SQL_URL")
    secret_key: str = os.getenv("FERNET_KEY")
    redis_url: RedisDsn = os.getenv("REDIS_URL")
    jwt_algorithm: str = os.getenv("JWT_ALGORITHM")
    jwt_expire: int = os.getenv("JWT_EXPIRE")


@lru_cache
def get_settings():
    return Settings()


settings = get_settings()

It's the same as below, I think. Because get_setting() with @lru_cache will always return the same object.:

import os
from functools import lru_cache

from pydantic import PostgresDsn, RedisDsn
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    asyncpg_url: PostgresDsn = os.getenv("SQL_URL")
    secret_key: str = os.getenv("FERNET_KEY")
    redis_url: RedisDsn = os.getenv("REDIS_URL")
    jwt_algorithm: str = os.getenv("JWT_ALGORITHM")
    jwt_expire: int = os.getenv("JWT_EXPIRE")


settings = Setting()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.