Skip to main content

base for flask server by Mixel Te

dependencies

Python 3.10 or later

alembic >= 1.16.4, < 2
cryptography >= 46.0.5, < 51
concurrent-log-handler >= 0.9.28, < 1
flask >= 3.1.1, < 4
flask_jwt_extended >= 4.7.1, < 5
PyJWT >= 2.0, < 3.0
PyMySQL >= 1.1.1, < 2
python-dotenv >= 1.0, < 2
sqlalchemy >= 2.0.45, < 2.1
sqlalchemy_serializer >= 1.5.5, < 2
typing_extensions >= 4.13.2, < 5
werkzeug >= 3.1.3, < 4

usage

scripts: bafser

Both bafser and python -m bafser load .env from the current working directory before running a command. Existing environment variables take precedence; a missing .env is allowed. Parent directories are not searched. For example, DBPATH in .env supplies a configuration value declared as db_path = "ENV:DBPATH". This loading applies to CLI commands; application entry points must load their own .env if needed.

init project: bafser init_project (existing generated files are kept; use --force to replace them)

With use_alembic = True, create an initial migration before starting the app: bafser alembic revision followed by bafser alembic upgrade.

run gunicorn -w 4 --threads 2 --worker-class gthread -b 0.0.0.0:80 main:app


or manually

copy bafser_config.example.py to project root as bafser_config.py

init alembic bafser alembic init (existing templates are kept; use --force to replace them)

create files:

.gitignore

.venv
*__pycache__*
/logs
/db
/images
/fonts
secret_key_jwt.txt
# data/_operations.py
from bafser import OperationsBase


class Operations(OperationsBase):
    oper_id = ("oper_id", "Operation description")
    oper_id2 = ("oper_id2", "Operation description")
    ...
# data/_roles.py
from bafser import RolesBase
from data._operations import Operations


class Roles(RolesBase):
    # admin = 1 is already set for admin role
    role_name = 2
    role_name2 = 3
    ...


Roles.ROLES = {
    # Roles.admin: {"name": "Admin", "operations": []} = 1 is auto created with all Operations
    Roles.role_name: {
        "name": "Role name",
        "operations": [
            Operations.oper_id,
            Operations.oper_id2,
        ]
    },
    Roles.role_name2: {
        "name": "Role name 2",
        "operations": [
            Operations.oper_id,
        ]
    },
}
# data/_tables.py
from bafser import TablesBase


class Tables(TablesBase):
    TableName = "TableName"
    AnotherTableName = "AnotherTableName"
# data/user.py
from bafser import UserBase


class User(UserBase):
    def __repr__(self):
        return f"<{self.__class__.__name__}> [{self.id}] {self.login}"
# data/some_table.py
from bafser import SqlAlchemyBase, ObjMixin
from data._tables import Tables


class SomeTable(SqlAlchemyBase, ObjMixin):
    __tablename__ = Tables.SomeTable
    ...
  • IdMixin adds id column
  • ObjMixin adds id and deleted columns
  • SingletonMixin adds id column

Mixins also provide get, query, and all. They use the request session by default; pass db_sess when working outside a request or within a specific transaction:

item = SomeTable.get(item_id)
item = SomeTable.get(item_id, db_sess=session, for_update=True)
items = SomeTable.all(db_sess=session)
# main.py
import sys
from bafser import AppConfig, create_app
from scripts.init_dev_values import init_dev_values


app, run = create_app(__name__, AppConfig(
    MESSAGE_TO_FRONTEND="",
    DEV_MODE="dev" in sys.argv,
    DELAY_MODE="delay" in sys.argv,
)
    .add_data_folder("FONTS_FOLDER", "fonts")
    .add_secret_key("API_SECRET_KEY", "secret_key_api.txt")
)

run(__name__ == "__main__", None, init_dev_values)

modifying User and Image

User:

from typing import Any
from typing_extensions import override
from sqlalchemy.orm import Session, Mapped, mapped_column
from bafser import UserBase, UserKwargs

from data._roles import Roles


class User(UserBase):
    newColumn: Mapped[str]

    @classmethod
    @override
    def new(cls, creator: UserBase, login: str, password: str, name: str, roles: list[int], newColumn: str, *, db_sess: Session | None = None):
        return super().new(creator, login, password, name, roles, db_sess=db_sess, newColumn=newColumn)

    @classmethod
    @override
    def _new(cls, db_sess: Session, user_kwargs: UserKwargs, *, newColumn: str, **kwargs: Any):
        return User(**user_kwargs, newColumn=newColumn)

    @classmethod
    @override
    def create_admin(cls, db_sess: Session):
        fake_creator = User.get_fake_system()
        return User.new(fake_creator, "admin", "admin", "Admin", [Roles.admin], "newColumnValue", db_sess=db_sess)

Image:

from typing import TypedDict
from typing_extensions import override
from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column

from bafser import Image as ImageBase, ImageKwargs, get_json_values
from test.data.user import User


class ImageJson(TypedDict):
    data: str
    name: str
    newColumnData: str


class Img(ImageBase):
    newColumn: Mapped[str]

    @classmethod
    @override
    def new(cls, creator: User, json: ImageJson):  # type: ignore
        return super().new(creator, json)

    @classmethod
    @override
    def _new(cls, creator: User, json: ImageJson, image_kwargs: ImageKwargs):  # type: ignore
        newColumnData, values_error = get_json_values(json, ("newColumnData", str))
        if values_error:
            return None, None, values_error
        img = Img(**image_kwargs, newColumn=newColumnData)
        changes = [("newColumn", newColumn)]
        return img, changes, None

csv header for requests log

reqid;ip;uid;asctime;method;url;message;code;json

UTC dates (2.12.3)

get_datetime_utc() returns the current instant as a timezone-aware UTC datetime. It is exported from both bafser and bafser.utils.

Set datetime_utc = True in bafser_config.py to use UTC for shared model timestamps and file logs. In this mode get_datetime_now() delegates to the UTC clock, parse_date() converts ISO offsets to UTC (naive input is already UTC), and model serialization includes a Z suffix. SQL DATETIME values store UTC without a timezone; convert existing local timestamps before enabling this mode. Without this setting the legacy behavior is preserved.

Metadata

Release files for bafser 2.12.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bafser 2.12.3
File Size Uploaded
bafser-2.12.3.tar.gz 65.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bafser 2.12.3
File Interpreter ABI Platform
bafser-2.12.3-py3-none-any.whl Python 3 none any Details

Total release size: 153.1 kB

Release files / bafser-2.12.3.tar.gz

Download URL bafser-2.12.3.tar.gz
Size 65.5 kB
Tags Source
SHA-256 checksum
How to use checksums
44da13f7ed810c2b57c6e22e0c6b38c9b071bbfc27db043dfa3ae78a93e12ca7
BLAKE2b-256 checksum
How to use checksums
b4b115883057cf344c9ab21eec64e3bd1f09e3ce29cbc692be96c0441b27d7ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / bafser-2.12.3-py3-none-any.whl

Download URL bafser-2.12.3-py3-none-any.whl
Size 87.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
86c05d547af74f8e9c35e589c491a3b96faceaa09a9552b62b523a6837fc5bd5
BLAKE2b-256 checksum
How to use checksums
e8a5a0573403d3c5fcfbd9b0aacb69d804577c0eedbb3fc8f87dd23ac9d64352
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.12.3 This release

2 release files

2.12.2

2 release files

2.9.0

2 release files

2.8.16

2 release files

2.8.15

2 release files

2.8.14

2 release files

2.8.9

2 release files

2.8.8

2 release files

2.8.7

2 release files

2.8.6

2 release files

2.8.5

2 release files

2.8.4

2 release files

2.8.3

2 release files

2.8.2

2 release files

2.8.1

2 release files

2.8.0

2 release files

2.7.1

2 release files

2.7.0

2 release files

2.6.1

2 release files

2.6.0

2 release files

2.5.3

2 release files

2.5.2

2 release files

2.5.1

2 release files

2.5.0

2 release files

2.4.5

2 release files

2.4.4

2 release files

2.4.3

2 release files

2.4.2

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.11

2 release files

2.2.10

2 release files

2.2.9

2 release files

2.2.8

2 release files

2.2.7

2 release files

2.2.6

2 release files

2.2.5

2 release files

2.2.4

2 release files

2.2.3

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2

2 release files

2.1.1

2 release files

2.1

2 release files

2.0.13

2 release files

2.0.12

2 release files

2.0.11

2 release files

2.0.10

2 release files

2.0.9

2 release files

2.0.8

2 release files

2.0.7

2 release files

2.0.6

2 release files

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.6

2 release files

1.5.12

2 release files

1.5.11

2 release files

1.5.10

2 release files

1.5.9

2 release files

1.5.8

2 release files

1.5.7

2 release files

1.5.6

2 release files

1.5.5

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.4.4

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page