Metadata-Version: 2.3
Name: flask-flac
Version: 0.20241022.1
Summary: Flask based library to help structure an application with an eye towards CLI apps, not just web.
Author-email: Randy Syring <randy@syrings.us>
License-Expression: MIT
Requires-Dist: appdirs
Requires-Dist: arrow
Requires-Dist: blazeutils
Requires-Dist: flask
Requires-Dist: pytest
Requires-Dist: pytest-cov
Requires-Dist: python-json-logger
Requires-Dist: requests
Provides-Extra: dev
Requires-Dist: anyio==4.6.2.post1; extra == 'dev'
Requires-Dist: appdirs==1.4.4; extra == 'dev'
Requires-Dist: argcomplete==3.5.1; extra == 'dev'
Requires-Dist: arrow==1.3.0; extra == 'dev'
Requires-Dist: binaryornot==0.4.4; extra == 'dev'
Requires-Dist: blazeutils==0.7.0; extra == 'dev'
Requires-Dist: blinker==1.8.2; extra == 'dev'
Requires-Dist: boolean-py==4.0; extra == 'dev'
Requires-Dist: cachecontrol==0.14.0; extra == 'dev'
Requires-Dist: certifi==2024.8.30; extra == 'dev'
Requires-Dist: cffi==1.17.1; extra == 'dev'
Requires-Dist: cfgv==3.4.0; extra == 'dev'
Requires-Dist: chardet==5.2.0; extra == 'dev'
Requires-Dist: charset-normalizer==3.4.0; extra == 'dev'
Requires-Dist: click==8.1.7; extra == 'dev'
Requires-Dist: colorlog==6.8.2; extra == 'dev'
Requires-Dist: cookiecutter==2.6.0; extra == 'dev'
Requires-Dist: coverage==7.6.3; extra == 'dev'
Requires-Dist: cryptography==43.0.1; extra == 'dev'
Requires-Dist: cyclonedx-python-lib==7.6.2; extra == 'dev'
Requires-Dist: defusedxml==0.7.1; extra == 'dev'
Requires-Dist: distlib==0.3.9; extra == 'dev'
Requires-Dist: faker==30.6.0; extra == 'dev'
Requires-Dist: filelock==3.16.1; extra == 'dev'
Requires-Dist: flask-sqlalchemy==3.1.1; extra == 'dev'
Requires-Dist: flask==3.0.3; extra == 'dev'
Requires-Dist: greenlet==3.1.1; extra == 'dev'
Requires-Dist: h11==0.14.0; extra == 'dev'
Requires-Dist: hatch==1.13.0; extra == 'dev'
Requires-Dist: hatchling==1.25.0; extra == 'dev'
Requires-Dist: html5lib==1.1; extra == 'dev'
Requires-Dist: httpcore==1.0.6; extra == 'dev'
Requires-Dist: httpx==0.27.2; extra == 'dev'
Requires-Dist: hyperlink==21.0.0; extra == 'dev'
Requires-Dist: identify==2.6.1; extra == 'dev'
Requires-Dist: idna==3.10; extra == 'dev'
Requires-Dist: iniconfig==2.0.0; extra == 'dev'
Requires-Dist: itsdangerous==2.2.0; extra == 'dev'
Requires-Dist: jaraco-classes==3.4.0; extra == 'dev'
Requires-Dist: jaraco-context==6.0.1; extra == 'dev'
Requires-Dist: jaraco-functools==4.1.0; extra == 'dev'
Requires-Dist: jeepney==0.8.0; extra == 'dev'
Requires-Dist: jinja2==3.1.4; extra == 'dev'
Requires-Dist: keyring==25.4.1; extra == 'dev'
Requires-Dist: license-expression==30.3.1; extra == 'dev'
Requires-Dist: markdown-it-py==3.0.0; extra == 'dev'
Requires-Dist: markupsafe==3.0.1; extra == 'dev'
Requires-Dist: mdurl==0.1.2; extra == 'dev'
Requires-Dist: more-itertools==10.5.0; extra == 'dev'
Requires-Dist: msgpack==1.1.0; extra == 'dev'
Requires-Dist: nodeenv==1.9.1; extra == 'dev'
Requires-Dist: nox==2024.10.9; extra == 'dev'
Requires-Dist: packageurl-python==0.15.6; extra == 'dev'
Requires-Dist: packaging==24.1; extra == 'dev'
Requires-Dist: pathspec==0.12.1; extra == 'dev'
Requires-Dist: pexpect==4.9.0; extra == 'dev'
Requires-Dist: pip-api==0.0.34; extra == 'dev'
Requires-Dist: pip-audit==2.7.3; extra == 'dev'
Requires-Dist: pip-requirements-parser==32.0.1; extra == 'dev'
Requires-Dist: pip==24.2; extra == 'dev'
Requires-Dist: platformdirs==4.3.6; extra == 'dev'
Requires-Dist: pluggy==1.5.0; extra == 'dev'
Requires-Dist: pre-commit==4.0.1; extra == 'dev'
Requires-Dist: ptyprocess==0.7.0; extra == 'dev'
Requires-Dist: py-serializable==1.1.2; extra == 'dev'
Requires-Dist: pycparser==2.22; extra == 'dev'
Requires-Dist: pygments==2.18.0; extra == 'dev'
Requires-Dist: pyparsing==3.2.0; extra == 'dev'
Requires-Dist: pytest-cov==5.0.0; extra == 'dev'
Requires-Dist: pytest==8.3.3; extra == 'dev'
Requires-Dist: python-dateutil==2.9.0.post0; extra == 'dev'
Requires-Dist: python-json-logger==2.0.7; extra == 'dev'
Requires-Dist: python-slugify==8.0.4; extra == 'dev'
Requires-Dist: pyyaml==6.0.2; extra == 'dev'
Requires-Dist: requests==2.32.3; extra == 'dev'
Requires-Dist: rich==13.9.2; extra == 'dev'
Requires-Dist: ruff==0.7.0; extra == 'dev'
Requires-Dist: secretstorage==3.3.3; extra == 'dev'
Requires-Dist: shellingham==1.5.4; extra == 'dev'
Requires-Dist: six==1.16.0; extra == 'dev'
Requires-Dist: sniffio==1.3.1; extra == 'dev'
Requires-Dist: sortedcontainers==2.4.0; extra == 'dev'
Requires-Dist: sqlalchemy-utils==0.41.2; extra == 'dev'
Requires-Dist: sqlalchemy==2.0.36; extra == 'dev'
Requires-Dist: text-unidecode==1.3; extra == 'dev'
Requires-Dist: toml==0.10.2; extra == 'dev'
Requires-Dist: tomli-w==1.1.0; extra == 'dev'
Requires-Dist: tomlkit==0.13.2; extra == 'dev'
Requires-Dist: trove-classifiers==2024.10.16; extra == 'dev'
Requires-Dist: types-python-dateutil==2.9.0.20241003; extra == 'dev'
Requires-Dist: typing-extensions==4.12.2; extra == 'dev'
Requires-Dist: urllib3==2.2.3; extra == 'dev'
Requires-Dist: userpath==1.9.2; extra == 'dev'
Requires-Dist: uv==0.4.23; extra == 'dev'
Requires-Dist: virtualenv==20.26.6; extra == 'dev'
Requires-Dist: webencodings==0.5.1; extra == 'dev'
Requires-Dist: werkzeug==3.0.4; extra == 'dev'
Requires-Dist: wrapt==1.16.0; extra == 'dev'
Requires-Dist: zstandard==0.23.0; extra == 'dev'
Provides-Extra: sqlalchemy
Requires-Dist: flask-sqlalchemy; extra == 'sqlalchemy'
Requires-Dist: sqlalchemy-utils; extra == 'sqlalchemy'
Description-Content-Type: text/markdown

# Flac

Flask based library to help structure an application with an eye towards CLI apps, not just web.


## Features

- App factory pattern
    - blueprints (web & CLI)
- CLI Integration
    - custom command
    - two-phase init for blueprints
- Configuration
    - .env & .flaskenv
    - from files
    - from environment
    - alternate settings for testing, dev, prod
- Logging
    - logs are probably cheap, don't prematurely optimize
    - centralize your logs to an aggregation service
    - .info logs are show/saved by default
    - cli output is plain text
    - saved logs are JSON
    - saved logs go to syslog, let devops handle the aggregation
- Testing
    - alternate DB URI
    - pytest & fixtures
- Flask-SQLAlchemy
    - ext init
    - fixtures to get db to ensure app context
- Celery
    - refresh process pool


- cli integration with the ability to customize the app's configuration using global cli options

    someapp --debug --with-sentry run-some-task

- pytest fixtures for app initialization
- demo cli test that uses separate process

## Develoment

### Copier Template

Project structure and tooling mostly derives from the [copier-py-package](https://github.com/level12/copier-py-package),
see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see [updates](https://github.com/level12/copier-py-package?tab=readme-ov-file#updates)

### Project Setup

From zero to hero (passing tests that is):

1. Ensure host dependencies are installed:

  - [reqs](https://github.com/level12/reqs): for virtualenv python deps
  - [mise](https://mise.jdx.dev/): for everything else, e.g. terraform, npm

2. Start docker service dependencies (if applicable):

   `docker compose up -d`

3. Run tests:

   `nox`

4. Use mise to activate the virtualenv for local dev

5. Install deps in active virtualenv:

    - `reqs bootstrap`
    - `reqs sync`

6. Configure pre-commit:

   `pre-commit install`


### Versions

Versions are date based.  Tools:

- Current version: `hatch version`
- Bump version based on date, tag, push: `mise run bump`
   - Options: `mise run bump -- --help`
