anchovy


Nameanchovy JSON
Version 1.0.0 PyPI version JSON
download
home_page
SummaryA minimal, unopinionated file processing engine intended for static website generation.
upload_time2024-02-04 03:52:59
maintainer
docs_urlNone
author
requires_python>=3.10
licenseApache-2.0
keywords static website generation html css template
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![PyPI - Project Version](https://img.shields.io/pypi/v/anchovy)](https://pypi.org/project/anchovy)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/anchovy)](https://pypi.org/project/anchovy)
[![GitHub - Project License](https://img.shields.io/github/license/pydsigner/anchovy)](https://github.com/pydsigner/anchovy)
[![GitHub - Code Size](https://img.shields.io/github/languages/code-size/pydsigner/anchovy)](https://github.com/pydsigner/anchovy)
[![codecov](https://codecov.io/gh/pydsigner/anchovy/graph/badge.svg?token=A8WRBWO3JG)](https://codecov.io/gh/pydsigner/anchovy)

# Anchovy

Anchovy is a minimal, unopinionated file-processing framework equipped with a
complete static website generation toolkit.

* **Minimal:** Anchovy’s core is around a thousand lines of code and has no
  mandatory dependencies. Plus, Anchovy can be used for real projects with just
  a few pip-installable extras, even if you want to preprocess CSS.

* **Unopinionated:** Anchovy offers a set of components which can be easily
  configured to your site’s exact requirements, without tediously ripping out
  or overriding entrenched behaviors. Anchovy does not assume you are building
  a blog or that you wish to design your templates in a specific way. You can
  even build things that aren’t websites! Plus, Anchovy operates on files, so
  it’s simple to integrate tools like imagemagick, dart-sass, or less.js if you
  need them.

* **Complete:** Anchovy comes with a dependency auditing system, allowing you
  to grab any component you want without installing anything but Anchovy and
  find out what you *will* need to run your build. Choose from a wealth of
  Steps, Anchovy’s modular file processors, for everything from rendering Jinja
  templates and minifying CSS to unpacking archives and thumbnailing images.
  Plus, add a few extra parameters or lines of configuration to get automatic
  intelligent minimum builds based on input checksums, and get a reproducible
  run artifact to boot— even if you want to fetch HTTP resources or write your
  own Steps. Iterate quickly by launching a lightweight development-grade web
  server once the build is complete.

## Installation

Anchovy has no essential prerequisites and can be installed with
`pip install anchovy` to get just the framework and a few built-in components,
but for typical usage `pip install anchovy[base]` is recommended. This will
pull in support for Jinja2 templating, markdown, minification, and Anchovy’s
CSS preprocessor. A full list of available extras may be found in the
[pyproject.toml](https://github.com/pydsigner/anchovy/blob/master/pyproject.toml) file.

Alternatively, Anchovy may be installed directly from source with
`pip install git+https://github.com/pydsigner/anchovy` or the corresponding
`pip install git+https://github.com/pydsigner/anchovy#egg=anchovy[base]`.

## Command Line Usage

Anchovy operates on config files written in Python, or even modules directly.

* `python -m anchovy -h`
* `anchovy -m mypackage.anchovyconf -o ../release/`
* `python -m anchovy mysite/anchovy_site.py -- -h`

### Show Me

Run `anchovy examples/code_index.py -s -p 8080`, then open a browser to
localhost:8080 (or click the link in the console). This example offers the most
extensive demonstration of Anchovy’s functionality as of version 1.0.

### What’s the Baseline?

Here’s minimal example performing about what the `staticjinja` markdown example
offers:

```python
from pathlib import Path

from anchovy import (
    DirectCopyStep,
    InputBuildSettings,
    JinjaMarkdownStep,
    OutputDirPathCalc,
    REMatcher,
    Rule,
)


# Optional, and can be overridden with CLI arguments.
SETTINGS = InputBuildSettings(
    input_dir=Path('site'),
    working_dir=Path('working'),
    output_dir=Path('build'),
    custody_cache=Path('build-cache.json'),
)
RULES = [
    # Ignore dotfiles found in either the input_dir or the working dir.
    Rule(
        (
            REMatcher(r'(.*/)*\..*', parent_dir='input_dir')
            | REMatcher(r'(.*/)*\..*', parent_dir='working_dir')
        ),
        None
    ),
    # Render markdown files, then stop processing them.
    Rule(
        REMatcher(r'.*\.md'),
        [OutputDirPathCalc('.html'), None],
        JinjaMarkdownStep()
    ),
    # Copy everything else in static/ directories through.
    Rule(
        REMatcher(r'(.*/)*static/.*', parent_dir='input_dir'),
        OutputDirPathCalc(),
        DirectCopyStep()
    ),
]
```

This example is very simple, but it’s legitimately enough to start with for a
small website, and offers an advantage over other minimal frameworks by putting
additional batteries within an arm’s reach. If we stored the configuration in
`config.py` and added a raw site like this:
```
site/
    static/
        styles.css
        toolbar.js
    base.jinja.html
    index.md
    about.md
    contact.md
```
 `python -m anchovy config.py` would produce output like this:
```
output/
    static/
        styles.css
        toolbar.js
    index.html
    about.html
    contact.html
```

This example can be found in runnable form as [examples/basic_site.py](https://github.com/pydsigner/anchovy/blob/master/examples/basic_site.py)
in the source distribution. Available command line arguments can be seen by
passing `-h`: `python -m anchovy examples/basic_site.py -- -h`. The `--` is
required because `anchovy` itself also accepts the flag.

## Programmatic Usage

Anchovy is very usable from the command line, but projects desiring to
customize behavior, for example by running tasks before or after pipeline
execution, may utilize `anchovy.cli.run_from_rules()`:

```python
import time
from pathlib import Path

from anchovy.cli import run_from_rules
from anchovy.core import Context

from my_site.config import SETTINGS, RULES


class MyContext(Context):
    def find_inputs(path: Path):
        # Only process files modified in the last hour.
        hour_ago = time.time() - 3600
        for candidate in super().find_inputs(path):
            if candidate.stat().st_mtime > hour_ago:
                yield candidate


def main():
    print('Pretending to run pre-pipeline tasks...')
    run_from_rules(SETTINGS, RULES, context_cls=MyContext)
    print('Pretending to run post-pipeline tasks...')


if __name__ == '__main__':
    main()
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "anchovy",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": "",
    "keywords": "static,website,generation,html,css,template",
    "author": "",
    "author_email": "Daniel Foerster <pydsigner@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/b7/b0/2ba6285443a3e403df55868f2c6a563a380e138a9be0a1bbc56b91504bf4/anchovy-1.0.0.tar.gz",
    "platform": null,
    "description": "[![PyPI - Project Version](https://img.shields.io/pypi/v/anchovy)](https://pypi.org/project/anchovy)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/anchovy)](https://pypi.org/project/anchovy)\n[![GitHub - Project License](https://img.shields.io/github/license/pydsigner/anchovy)](https://github.com/pydsigner/anchovy)\n[![GitHub - Code Size](https://img.shields.io/github/languages/code-size/pydsigner/anchovy)](https://github.com/pydsigner/anchovy)\n[![codecov](https://codecov.io/gh/pydsigner/anchovy/graph/badge.svg?token=A8WRBWO3JG)](https://codecov.io/gh/pydsigner/anchovy)\n\n# Anchovy\n\nAnchovy is a minimal, unopinionated file-processing framework equipped with a\ncomplete static website generation toolkit.\n\n* **Minimal:** Anchovy\u2019s core is around a thousand lines of code and has no\n  mandatory dependencies. Plus, Anchovy can be used for real projects with just\n  a few pip-installable extras, even if you want to preprocess CSS.\n\n* **Unopinionated:** Anchovy offers a set of components which can be easily\n  configured to your site\u2019s exact requirements, without tediously ripping out\n  or overriding entrenched behaviors. Anchovy does not assume you are building\n  a blog or that you wish to design your templates in a specific way. You can\n  even build things that aren\u2019t websites! Plus, Anchovy operates on files, so\n  it\u2019s simple to integrate tools like imagemagick, dart-sass, or less.js if you\n  need them.\n\n* **Complete:** Anchovy comes with a dependency auditing system, allowing you\n  to grab any component you want without installing anything but Anchovy and\n  find out what you *will* need to run your build. Choose from a wealth of\n  Steps, Anchovy\u2019s modular file processors, for everything from rendering Jinja\n  templates and minifying CSS to unpacking archives and thumbnailing images.\n  Plus, add a few extra parameters or lines of configuration to get automatic\n  intelligent minimum builds based on input checksums, and get a reproducible\n  run artifact to boot\u2014 even if you want to fetch HTTP resources or write your\n  own Steps. Iterate quickly by launching a lightweight development-grade web\n  server once the build is complete.\n\n## Installation\n\nAnchovy has no essential prerequisites and can be installed with\n`pip install anchovy` to get just the framework and a few built-in components,\nbut for typical usage `pip install anchovy[base]` is recommended. This will\npull in support for Jinja2 templating, markdown, minification, and Anchovy\u2019s\nCSS preprocessor. A full list of available extras may be found in the\n[pyproject.toml](https://github.com/pydsigner/anchovy/blob/master/pyproject.toml) file.\n\nAlternatively, Anchovy may be installed directly from source with\n`pip install git+https://github.com/pydsigner/anchovy` or the corresponding\n`pip install git+https://github.com/pydsigner/anchovy#egg=anchovy[base]`.\n\n## Command Line Usage\n\nAnchovy operates on config files written in Python, or even modules directly.\n\n* `python -m anchovy -h`\n* `anchovy -m mypackage.anchovyconf -o ../release/`\n* `python -m anchovy mysite/anchovy_site.py -- -h`\n\n### Show Me\n\nRun `anchovy examples/code_index.py -s -p 8080`, then open a browser to\nlocalhost:8080 (or click the link in the console). This example offers the most\nextensive demonstration of Anchovy\u2019s functionality as of version 1.0.\n\n### What\u2019s the Baseline?\n\nHere\u2019s minimal example performing about what the `staticjinja` markdown example\noffers:\n\n```python\nfrom pathlib import Path\n\nfrom anchovy import (\n    DirectCopyStep,\n    InputBuildSettings,\n    JinjaMarkdownStep,\n    OutputDirPathCalc,\n    REMatcher,\n    Rule,\n)\n\n\n# Optional, and can be overridden with CLI arguments.\nSETTINGS = InputBuildSettings(\n    input_dir=Path('site'),\n    working_dir=Path('working'),\n    output_dir=Path('build'),\n    custody_cache=Path('build-cache.json'),\n)\nRULES = [\n    # Ignore dotfiles found in either the input_dir or the working dir.\n    Rule(\n        (\n            REMatcher(r'(.*/)*\\..*', parent_dir='input_dir')\n            | REMatcher(r'(.*/)*\\..*', parent_dir='working_dir')\n        ),\n        None\n    ),\n    # Render markdown files, then stop processing them.\n    Rule(\n        REMatcher(r'.*\\.md'),\n        [OutputDirPathCalc('.html'), None],\n        JinjaMarkdownStep()\n    ),\n    # Copy everything else in static/ directories through.\n    Rule(\n        REMatcher(r'(.*/)*static/.*', parent_dir='input_dir'),\n        OutputDirPathCalc(),\n        DirectCopyStep()\n    ),\n]\n```\n\nThis example is very simple, but it\u2019s legitimately enough to start with for a\nsmall website, and offers an advantage over other minimal frameworks by putting\nadditional batteries within an arm\u2019s reach. If we stored the configuration in\n`config.py` and added a raw site like this:\n```\nsite/\n    static/\n        styles.css\n        toolbar.js\n    base.jinja.html\n    index.md\n    about.md\n    contact.md\n```\n `python -m anchovy config.py` would produce output like this:\n```\noutput/\n    static/\n        styles.css\n        toolbar.js\n    index.html\n    about.html\n    contact.html\n```\n\nThis example can be found in runnable form as [examples/basic_site.py](https://github.com/pydsigner/anchovy/blob/master/examples/basic_site.py)\nin the source distribution. Available command line arguments can be seen by\npassing `-h`: `python -m anchovy examples/basic_site.py -- -h`. The `--` is\nrequired because `anchovy` itself also accepts the flag.\n\n## Programmatic Usage\n\nAnchovy is very usable from the command line, but projects desiring to\ncustomize behavior, for example by running tasks before or after pipeline\nexecution, may utilize `anchovy.cli.run_from_rules()`:\n\n```python\nimport time\nfrom pathlib import Path\n\nfrom anchovy.cli import run_from_rules\nfrom anchovy.core import Context\n\nfrom my_site.config import SETTINGS, RULES\n\n\nclass MyContext(Context):\n    def find_inputs(path: Path):\n        # Only process files modified in the last hour.\n        hour_ago = time.time() - 3600\n        for candidate in super().find_inputs(path):\n            if candidate.stat().st_mtime > hour_ago:\n                yield candidate\n\n\ndef main():\n    print('Pretending to run pre-pipeline tasks...')\n    run_from_rules(SETTINGS, RULES, context_cls=MyContext)\n    print('Pretending to run post-pipeline tasks...')\n\n\nif __name__ == '__main__':\n    main()\n```\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "A minimal, unopinionated file processing engine intended for static website generation.",
    "version": "1.0.0",
    "project_urls": {
        "Source": "https://github.com/pydsigner/anchovy"
    },
    "split_keywords": [
        "static",
        "website",
        "generation",
        "html",
        "css",
        "template"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "19e13f5a1cdbcb75a1b491f59db5bdfc73e6a7fc122411e3fdc3ba7ee0638f0a",
                "md5": "cbe7eec7bbedc4f1d963a61705e32b8e",
                "sha256": "d9ed77322ddad83f8a48711cb76fcb06385f66d02eb1bd527a3e5911c0a2915e"
            },
            "downloads": -1,
            "filename": "anchovy-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "cbe7eec7bbedc4f1d963a61705e32b8e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 37435,
            "upload_time": "2024-02-04T03:52:57",
            "upload_time_iso_8601": "2024-02-04T03:52:57.869089Z",
            "url": "https://files.pythonhosted.org/packages/19/e1/3f5a1cdbcb75a1b491f59db5bdfc73e6a7fc122411e3fdc3ba7ee0638f0a/anchovy-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b7b02ba6285443a3e403df55868f2c6a563a380e138a9be0a1bbc56b91504bf4",
                "md5": "252353ac4f3bc7b8dda4cf4f19eb8cba",
                "sha256": "276ca421bf165f0d4b83d96f3a9206d4ecbbacd7d0e297ed5ae6730925f75988"
            },
            "downloads": -1,
            "filename": "anchovy-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "252353ac4f3bc7b8dda4cf4f19eb8cba",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 3201877,
            "upload_time": "2024-02-04T03:52:59",
            "upload_time_iso_8601": "2024-02-04T03:52:59.864136Z",
            "url": "https://files.pythonhosted.org/packages/b7/b0/2ba6285443a3e403df55868f2c6a563a380e138a9be0a1bbc56b91504bf4/anchovy-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-04 03:52:59",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "pydsigner",
    "github_project": "anchovy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "anchovy"
}
        
Elapsed time: 0.19075s