cookiecutter-aiohttp-sqlalchemy

Fat and opinionated cookiecutter template for building async Web Apps powered by Aiohttp, SQLAlchemy and Swagger.

Check out the Features section below for a short description of what this box packs for you. The Code Examples section showcases a code example of an async API using an SQLAlchemy Base Model.

If you want to see a working example web app generated using this cookiecutter-template, then please head over to /examples directory.

Contents

Features

Requirements

Quick Start

First, grab cookiecutter if you don't have it and start the generation process:

$ pip install cookiecutter
$ cookiecutter https://github.com/aalhour/cookiecutter-aiohttp-sqlalchemy

Either run everything with Docker and Docker-compose, which will also spin-up a PostgreSQL side-car instance, as follows:

$ docker-compose up

Or, go the manual way and install everything locally via the Makefile:

$ make install

Once installed manually, copy the config file template over to ~/.config/<your-app-name>.conf. It is important that the file name matches the application name you entered in the cookiecutter generation process:

$ cp config/example.conf ~/.config/<your-app-name>.conf

Next thing is, you need to customize your config file and enter your database details under the [db] section, please follow the config file:

$ cat ~/.config/<your-app-name>.conf

[db]
host = localhost
port = 5432
name = <database_name>
schema = <schema_name>
user = <database_user>

Lastly, start the application using the Pythonic entry point:

$ venv/bin/run_<your-app-name>

Code Examples

The following is an example API code that tries to query the database using an SQLAlchemy Declarative Model:

class UsersApi:
    async def get_user_by_id(self, request):
        """
        GET /api/v1.0/users/<id>
        """
        user_id = request.match_info.get('id')

        async with transactional_session() as db:
            # `User` is an SQLAlchemy declarative class
            user = await User.get_by_id(user_id, db)

            return self.json_response(user.serialized)
class User(db.BaseModel):
    """
    Data model for the User database table.
    """
    __tablename__ = 'user'

    id = Column(INTEGER, primary_key=True, autoincrement=True)

    def __init__(self, id_=None, name=None):
        self.id = id_

    @classmethod
    async def get_by_id(cls, id_: int, session: Session) -> "User":
        """
        Get user by ID from the database

        :param id_: User ID
        :param session: Database session object
        :return: User instance if user exists; otherwise, None
        """
        # Run the SQLAlchemy session.query(Example).get() function in the background
        return await run_async(session.query(cls).get, (id_,))

The template comes with pre-packaged asyncio utility functions and classes to aid querying the database via SQLALchemy declarative models in the background, the above mentioned transactional_session context-manager, run_async function and db.BaseModel class will be generated for you as part of the cookiecutter template.

If you want to see a working example web app generated using this cookiecutter-template, then please head over to /examples directory.