mutemplate


Namemutemplate JSON
Version 1.4 PyPI version JSON
download
home_pageNone
SummaryCompile template files into a standalone python file
upload_time2024-12-05 03:29:21
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseGPLv3
keywords micropython microdot utemplate
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ## MUTEMPLATE - Compiles Template Files into a Standalone Python File
[![PyPi](https://img.shields.io/pypi/v/mutemplate)](https://pypi.org/project/mutemplate/)
[![AUR](https://img.shields.io/aur/version/mutemplate)](https://aur.archlinux.org/packages/mutemplate/)

[`mutemplate`][mutemplate] is a command line tool you run on your
development host/PC to compile one or more template text files into
a single dynamically created stand-alone Python source file which can be
imported into your project and rendered by specifying the template name
and it's parameter arguments. `mutemplate` creates very lightweight and
memory-efficient templates which are primarily designed for resource
constrained environments such as [MicroPython][mp] on a
micro-controller, although created templates can be used with standard
Python also. `mutemplate` is derived from [`utemplate`][utemplate] and
uses the same template format which is very similar to
[`Django`][django] and [`Jinja`][jinja] templates. (e.g. `{% if %}`,
`{{var}}`).

Only essential template features are offered, for example, "filters"
(`{{var|filter}}`) are syntactic sugar for function calls so are not
implemented, function calls can be used directly instead:
`{{filter(var)}}`).

`mutemplate` compiles templates to Python source code. Think of a
compiled template as a enhanced "`f`" string that can embed `for` loops
and `if/else` conditionals evaluated for the arguments given at
run-time. A `generate()` generator function can be iterated over to
produce consecutive sub-strings of the rendered template. This allows
for minimal memory usage during template substitution and output.
Alternatively, the `render()` function can be used to return the entire
rendered template as a single string.

`mutemplate` provides the following two commands:

|Command  |Alias|Description                                                          |
|---------|-----|---------------------------------------------------------------------|
|`compile`|`c`  |Compile one or more template files into a single Python source file. |
|`render` |`r`  |Render given templates + arguments to output, for exercising/testing.|

These are described in detail in the later [Usage](#usage) section.

This utility has been developed and tested on Linux and should work on
Mac OS and Windows but has not been tried on those platforms. Raise an
issue or start a discussion on the [`mutemplate`][mutemplate] GitHub site
if you want.

## Syntax Reference

- `{{<expr>}}` - evaluates the given Python `<expr>` expression,
  converting it to a string and outputting to rendered content. Can be a
  bare variable name, or a function call, a yield from/await
  expressions, etc.
- `{% if <expr> %}, {% elif <expr> %}, {% else %}, {% endif %}` - analogous to Python's if statement.
- `{% for <var> in <expr> %}, {% endfor %}` - analogous to Python's for statement.
- `{% while <expr> %}, {% endwhile %}` - analogous to Python's while statement.
- `{% set <var> = <expr> %}` - assignment statement.
- `{% include "name.tpl" %}` - include another template. The
name can be a string literal or a variable, e.g. `{% include {{name}} %}`.
- `{# this is a comment #}` - comment line which is not compiled into the template.

Note that all expressions and statements of the types above must be on a single line.

## Template Variables Namespace

`mutemplate` uses a unique approach to pass template variables from your program
into the template. The user passes values to a `generate(*args,
**kwargs)` or `render(*args, **kwargs)` function as keyword and/or dict
arguments, specifically anything the Python [`dict()` constructor can
accept](https://docs.python.org/3/library/stdtypes.html#dict). The passed
keyword arguments are stored as attributes in a `t` namespace which is passed as
the single argument to a template to access the variables, e.g. the user passes
`avalue=5` and it is accessed within the template as `A value = {{t.avalue}}`.

A child template (i.e. a template included from another template) automatically
receives the same `t` namespace argument although you can change and/or add
attribute values by adding keyword arguments to the `include` line. For example,
`{% include name.tpl name="mary" %}` will change the previous example `t.name`
to `mary` whereas `{% include name.tpl name2="mary" %}` will pass `t.name` as
`mark` (i.e. as it was passed to the parent template), and add `t.name2` as
`mary`.

## Example

Create some source template files in a directory on your PC, e.g. in
`templates/*.tpl`. Wherever you want an argument to be substituted in
the template at runtime, use `{{t.var}}` or `{% if t.var %}` etc.
An example simple template file may be:

```sh
$ cat templates/hello.tpl
...
Hello, {{t.name}}!
...
```

Then run the compiler at the command line on your PC:

```sh
$ mutemplate compile -o templates.py templates/*.tpl
```

This compiles all the template files in `templates/*.tpl` into a single
newly created `./templates.py` file. Copy that single file (or just the
`.mpy` bytecode) to your MicroPython project, import it, and use it as
follows:

```python
from microdot import Response
from templates import Template
..
return Response(body=Template("hello").generate(name="mark"))
```

This example is using [Microdot][microdot] to output a web page and is
using `mutemplate` to provide output in "string chunks" which is
the [most efficient
approach](https://microdot.readthedocs.io/en/latest/intro.html#streaming-responses).
You can alternately return the complete string by using `render()` in
the above instead of `generate()`.

> Note: if your template is HTML, then don't forget to set the `Content-Type`
> header for Microdot.

```python
return Response(body=Template("a_html_template").generate(data=data),
                headers={'Content-Type': 'text/html'}
```

More simple text examples are available in the [examples/](examples/)
directory.

## Render Command

Apart from the primary `compile` command line argument, a `render` command is
also provided to render templates to your screen for checking and testing. You
must specify the name of a previously compiled `templates.py` file, the template
name, and it's keyword arguments. Example usage for the above template:

```sh
$ mutemplate render templates.py hello name=mark
```

Arguments must be passed as `name=value` pairs. The value is converted to a
native Python type if possible, otherwise it is treated as a string.
`name=mark` is passed as a string (e.g. same as `'name="mark"'`), `age=42` would
be passed as an int, `values=[1,2,3]` would be passed as a list, etc. You may
need to brush on [shell quoting rules](https://mywiki.wooledge.org/Quotes)
if you want to get tricky with this.

## Differences from `utemplate`

1. `mutemplate` is a command line tool only. It produces a single python
file containing all your compiled templates so no run time compilation
occurs on your Micropython device and no dynamic imports are done by the
template engine.

2. The `utemplate` "`args`"" parameter is not recognised and an error is
reported if it is used in `mutemplate` templates. `utemplate` needs the
`args` parameter to assign values to variable names based on the order
you pass them to the template function but you define the relationship
`var=value` in the call for `mutemplate` so order is not relevant. Note
an advantage of the `mutemplate` approach is that to add a new template
variable you only need to add it to the template and to the calling
function but `utemplate` requires you to also add it to the `args`
parameter line and you also must ensure you maintain correct order which
is easy to get wrong. Also, the clear distinction in your templates
between internal variables (i.e. temporary loop counters/variables etc)
and externally passed-in values (i.e. those in the `t.*` namespace) is
useful.

3. `utemplate` compiles and stores multiple copies of child templates
when they are included multiple times from different parent templates
but `mutemplate` compiles and stores every template once only. All
`mutemplate` parent templates link to the one same child template. E.g.
if you have 10 templates, all including a common `header.tpl` and a
`footer.tpl` then `utemplate` will compile and store 10 copies of the
`header` templates + 10 copies of the `footer` templates, `mutemplate`
will compile and store 1 of each only.

4. `utemplate` (which appears to be unmaintained - no activity for 3
years) has an issue where it breaks and `yields` more sub-strings then
it needs to (whenever it hits **any** "`{`" character) but the parser
has been improved in `mutemplate` to avoid this. `mutemplate` only
breaks to a new `yield` when it must for a Python statement or
expression, so templates are rendered a little more efficiently and
quickly.

5. `mutemplate` also allows `{# comment #}` tags which are missing from
`utemplate` but are provided by [`Django`][django] and [`Jinja`][jinja]
templates and are simple to implement so are added for consistency.

## Usage

Type `mutemplate` or `mutemplate -h` to view the usage summary:

```
usage: mutemplate [-h] {compile,c,render,r} ...

Command line tool to compile one or more template text files into a single
importable python source file.

options:
  -h, --help            show this help message and exit

Commands:
  {compile,c,render,r}
    compile (c)         Compile one or more template files into a single
                        Python source file.
    render (r)          Render given templates + arguments to output, for
                        exercising/testing.
```

Type `mutemplate <command> -h` to see specific help/usage for any
individual command:

### Command `compile`

```
usage: mutemplate compile [-h] [-o OUTFILE] [-w] [-q]
                           template_file [template_file ...]

Compile one or more template files into a single Python source file.

positional arguments:
  template_file         input template file[s]

options:
  -h, --help            show this help message and exit
  -o OUTFILE, --outfile OUTFILE
                        output file, default is stdout
  -w, --watch           watch specified files forever and run on any change
  -q, --quiet           do not print any informational messages

aliases: c
```

### Command `render`

```
usage: mutemplate render [-h] [-d] template_file template_name [args ...]

Render given templates + arguments to output, for exercising/testing.

positional arguments:
  template_file    python template file
  template_name    name of template to render
  args             arguments for template

options:
  -h, --help       show this help message and exit
  -d, --delineate  delineate chunks with "|" in generated output

aliases: r
```

## Installation and Upgrade

Python 3.7 or later is required. Arch Linux users can install
[`mutemplate` from the
AUR](https://aur.archlinux.org/packages/mutemplate) and skip this
section.

The easiest way to install [`mutemplate`][mutemplate] is to use
[`pipx`][pipx] (or [`pipxu`][pipxu], or [`uv tool`][uvtool]).

```sh
$ pipx install mutemplate
```

To upgrade:

```sh
$ pipx upgrade mutemplate
```

To uninstall:

```sh
$ pipx uninstall mutemplate
```

## License

Copyright (C) 2024 Mark Blakeney. This program is distributed under the
terms of the GNU General Public License. This program is free software:
you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or any later version. This program is
distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at
<http://www.gnu.org/licenses/> for more details.

[mutemplate]: https://github.com/bulletmark/mutemplate
[utemplate]: https://github.com/pfalcon/utemplate
[mp]: https://micropython.org/
[microdot]: https://microdot.readthedocs.io/
[django]: https://docs.djangoproject.com/en/5.0/ref/templates/
[jinja]: https://jinja.palletsprojects.com/en/3.1.x/templates/
[pipx]: https://github.com/pypa/pipx
[pipxu]: https://github.com/bulletmark/pipxu
[uvtool]: https://docs.astral.sh/uv/guides/tools/#installing-tools

<!-- vim: se ai syn=markdown: -->

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "mutemplate",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "micropython, microdot, utemplate",
    "author": null,
    "author_email": "Mark Blakeney <mark.blakeney@bullet-systems.net>",
    "download_url": "https://files.pythonhosted.org/packages/ee/c3/e04a9806e3a01411be4a876148936060e21b1efd16a29c2221dcfe6bcc57/mutemplate-1.4.tar.gz",
    "platform": null,
    "description": "## MUTEMPLATE - Compiles Template Files into a Standalone Python File\n[![PyPi](https://img.shields.io/pypi/v/mutemplate)](https://pypi.org/project/mutemplate/)\n[![AUR](https://img.shields.io/aur/version/mutemplate)](https://aur.archlinux.org/packages/mutemplate/)\n\n[`mutemplate`][mutemplate] is a command line tool you run on your\ndevelopment host/PC to compile one or more template text files into\na single dynamically created stand-alone Python source file which can be\nimported into your project and rendered by specifying the template name\nand it's parameter arguments. `mutemplate` creates very lightweight and\nmemory-efficient templates which are primarily designed for resource\nconstrained environments such as [MicroPython][mp] on a\nmicro-controller, although created templates can be used with standard\nPython also. `mutemplate` is derived from [`utemplate`][utemplate] and\nuses the same template format which is very similar to\n[`Django`][django] and [`Jinja`][jinja] templates. (e.g. `{% if %}`,\n`{{var}}`).\n\nOnly essential template features are offered, for example, \"filters\"\n(`{{var|filter}}`) are syntactic sugar for function calls so are not\nimplemented, function calls can be used directly instead:\n`{{filter(var)}}`).\n\n`mutemplate` compiles templates to Python source code. Think of a\ncompiled template as a enhanced \"`f`\" string that can embed `for` loops\nand `if/else` conditionals evaluated for the arguments given at\nrun-time. A `generate()` generator function can be iterated over to\nproduce consecutive sub-strings of the rendered template. This allows\nfor minimal memory usage during template substitution and output.\nAlternatively, the `render()` function can be used to return the entire\nrendered template as a single string.\n\n`mutemplate` provides the following two commands:\n\n|Command  |Alias|Description                                                          |\n|---------|-----|---------------------------------------------------------------------|\n|`compile`|`c`  |Compile one or more template files into a single Python source file. |\n|`render` |`r`  |Render given templates + arguments to output, for exercising/testing.|\n\nThese are described in detail in the later [Usage](#usage) section.\n\nThis utility has been developed and tested on Linux and should work on\nMac OS and Windows but has not been tried on those platforms. Raise an\nissue or start a discussion on the [`mutemplate`][mutemplate] GitHub site\nif you want.\n\n## Syntax Reference\n\n- `{{<expr>}}` - evaluates the given Python `<expr>` expression,\n  converting it to a string and outputting to rendered content. Can be a\n  bare variable name, or a function call, a yield from/await\n  expressions, etc.\n- `{% if <expr> %}, {% elif <expr> %}, {% else %}, {% endif %}` - analogous to Python's if statement.\n- `{% for <var> in <expr> %}, {% endfor %}` - analogous to Python's for statement.\n- `{% while <expr> %}, {% endwhile %}` - analogous to Python's while statement.\n- `{% set <var> = <expr> %}` - assignment statement.\n- `{% include \"name.tpl\" %}` - include another template. The\nname can be a string literal or a variable, e.g. `{% include {{name}} %}`.\n- `{# this is a comment #}` - comment line which is not compiled into the template.\n\nNote that all expressions and statements of the types above must be on a single line.\n\n## Template Variables Namespace\n\n`mutemplate` uses a unique approach to pass template variables from your program\ninto the template. The user passes values to a `generate(*args,\n**kwargs)` or `render(*args, **kwargs)` function as keyword and/or dict\narguments, specifically anything the Python [`dict()` constructor can\naccept](https://docs.python.org/3/library/stdtypes.html#dict). The passed\nkeyword arguments are stored as attributes in a `t` namespace which is passed as\nthe single argument to a template to access the variables, e.g. the user passes\n`avalue=5` and it is accessed within the template as `A value = {{t.avalue}}`.\n\nA child template (i.e. a template included from another template) automatically\nreceives the same `t` namespace argument although you can change and/or add\nattribute values by adding keyword arguments to the `include` line. For example,\n`{% include name.tpl name=\"mary\" %}` will change the previous example `t.name`\nto `mary` whereas `{% include name.tpl name2=\"mary\" %}` will pass `t.name` as\n`mark` (i.e. as it was passed to the parent template), and add `t.name2` as\n`mary`.\n\n## Example\n\nCreate some source template files in a directory on your PC, e.g. in\n`templates/*.tpl`. Wherever you want an argument to be substituted in\nthe template at runtime, use `{{t.var}}` or `{% if t.var %}` etc.\nAn example simple template file may be:\n\n```sh\n$ cat templates/hello.tpl\n...\nHello, {{t.name}}!\n...\n```\n\nThen run the compiler at the command line on your PC:\n\n```sh\n$ mutemplate compile -o templates.py templates/*.tpl\n```\n\nThis compiles all the template files in `templates/*.tpl` into a single\nnewly created `./templates.py` file. Copy that single file (or just the\n`.mpy` bytecode) to your MicroPython project, import it, and use it as\nfollows:\n\n```python\nfrom microdot import Response\nfrom templates import Template\n..\nreturn Response(body=Template(\"hello\").generate(name=\"mark\"))\n```\n\nThis example is using [Microdot][microdot] to output a web page and is\nusing `mutemplate` to provide output in \"string chunks\" which is\nthe [most efficient\napproach](https://microdot.readthedocs.io/en/latest/intro.html#streaming-responses).\nYou can alternately return the complete string by using `render()` in\nthe above instead of `generate()`.\n\n> Note: if your template is HTML, then don't forget to set the `Content-Type`\n> header for Microdot.\n\n```python\nreturn Response(body=Template(\"a_html_template\").generate(data=data),\n                headers={'Content-Type': 'text/html'}\n```\n\nMore simple text examples are available in the [examples/](examples/)\ndirectory.\n\n## Render Command\n\nApart from the primary `compile` command line argument, a `render` command is\nalso provided to render templates to your screen for checking and testing. You\nmust specify the name of a previously compiled `templates.py` file, the template\nname, and it's keyword arguments. Example usage for the above template:\n\n```sh\n$ mutemplate render templates.py hello name=mark\n```\n\nArguments must be passed as `name=value` pairs. The value is converted to a\nnative Python type if possible, otherwise it is treated as a string.\n`name=mark` is passed as a string (e.g. same as `'name=\"mark\"'`), `age=42` would\nbe passed as an int, `values=[1,2,3]` would be passed as a list, etc. You may\nneed to brush on [shell quoting rules](https://mywiki.wooledge.org/Quotes)\nif you want to get tricky with this.\n\n## Differences from `utemplate`\n\n1. `mutemplate` is a command line tool only. It produces a single python\nfile containing all your compiled templates so no run time compilation\noccurs on your Micropython device and no dynamic imports are done by the\ntemplate engine.\n\n2. The `utemplate` \"`args`\"\" parameter is not recognised and an error is\nreported if it is used in `mutemplate` templates. `utemplate` needs the\n`args` parameter to assign values to variable names based on the order\nyou pass them to the template function but you define the relationship\n`var=value` in the call for `mutemplate` so order is not relevant. Note\nan advantage of the `mutemplate` approach is that to add a new template\nvariable you only need to add it to the template and to the calling\nfunction but `utemplate` requires you to also add it to the `args`\nparameter line and you also must ensure you maintain correct order which\nis easy to get wrong. Also, the clear distinction in your templates\nbetween internal variables (i.e. temporary loop counters/variables etc)\nand externally passed-in values (i.e. those in the `t.*` namespace) is\nuseful.\n\n3. `utemplate` compiles and stores multiple copies of child templates\nwhen they are included multiple times from different parent templates\nbut `mutemplate` compiles and stores every template once only. All\n`mutemplate` parent templates link to the one same child template. E.g.\nif you have 10 templates, all including a common `header.tpl` and a\n`footer.tpl` then `utemplate` will compile and store 10 copies of the\n`header` templates + 10 copies of the `footer` templates, `mutemplate`\nwill compile and store 1 of each only.\n\n4. `utemplate` (which appears to be unmaintained - no activity for 3\nyears) has an issue where it breaks and `yields` more sub-strings then\nit needs to (whenever it hits **any** \"`{`\" character) but the parser\nhas been improved in `mutemplate` to avoid this. `mutemplate` only\nbreaks to a new `yield` when it must for a Python statement or\nexpression, so templates are rendered a little more efficiently and\nquickly.\n\n5. `mutemplate` also allows `{# comment #}` tags which are missing from\n`utemplate` but are provided by [`Django`][django] and [`Jinja`][jinja]\ntemplates and are simple to implement so are added for consistency.\n\n## Usage\n\nType `mutemplate` or `mutemplate -h` to view the usage summary:\n\n```\nusage: mutemplate [-h] {compile,c,render,r} ...\n\nCommand line tool to compile one or more template text files into a single\nimportable python source file.\n\noptions:\n  -h, --help            show this help message and exit\n\nCommands:\n  {compile,c,render,r}\n    compile (c)         Compile one or more template files into a single\n                        Python source file.\n    render (r)          Render given templates + arguments to output, for\n                        exercising/testing.\n```\n\nType `mutemplate <command> -h` to see specific help/usage for any\nindividual command:\n\n### Command `compile`\n\n```\nusage: mutemplate compile [-h] [-o OUTFILE] [-w] [-q]\n                           template_file [template_file ...]\n\nCompile one or more template files into a single Python source file.\n\npositional arguments:\n  template_file         input template file[s]\n\noptions:\n  -h, --help            show this help message and exit\n  -o OUTFILE, --outfile OUTFILE\n                        output file, default is stdout\n  -w, --watch           watch specified files forever and run on any change\n  -q, --quiet           do not print any informational messages\n\naliases: c\n```\n\n### Command `render`\n\n```\nusage: mutemplate render [-h] [-d] template_file template_name [args ...]\n\nRender given templates + arguments to output, for exercising/testing.\n\npositional arguments:\n  template_file    python template file\n  template_name    name of template to render\n  args             arguments for template\n\noptions:\n  -h, --help       show this help message and exit\n  -d, --delineate  delineate chunks with \"|\" in generated output\n\naliases: r\n```\n\n## Installation and Upgrade\n\nPython 3.7 or later is required. Arch Linux users can install\n[`mutemplate` from the\nAUR](https://aur.archlinux.org/packages/mutemplate) and skip this\nsection.\n\nThe easiest way to install [`mutemplate`][mutemplate] is to use\n[`pipx`][pipx] (or [`pipxu`][pipxu], or [`uv tool`][uvtool]).\n\n```sh\n$ pipx install mutemplate\n```\n\nTo upgrade:\n\n```sh\n$ pipx upgrade mutemplate\n```\n\nTo uninstall:\n\n```sh\n$ pipx uninstall mutemplate\n```\n\n## License\n\nCopyright (C) 2024 Mark Blakeney. This program is distributed under the\nterms of the GNU General Public License. This program is free software:\nyou can redistribute it and/or modify it under the terms of the GNU\nGeneral Public License as published by the Free Software Foundation,\neither version 3 of the License, or any later version. This program is\ndistributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at\n<http://www.gnu.org/licenses/> for more details.\n\n[mutemplate]: https://github.com/bulletmark/mutemplate\n[utemplate]: https://github.com/pfalcon/utemplate\n[mp]: https://micropython.org/\n[microdot]: https://microdot.readthedocs.io/\n[django]: https://docs.djangoproject.com/en/5.0/ref/templates/\n[jinja]: https://jinja.palletsprojects.com/en/3.1.x/templates/\n[pipx]: https://github.com/pypa/pipx\n[pipxu]: https://github.com/bulletmark/pipxu\n[uvtool]: https://docs.astral.sh/uv/guides/tools/#installing-tools\n\n<!-- vim: se ai syn=markdown: -->\n",
    "bugtrack_url": null,
    "license": "GPLv3",
    "summary": "Compile template files into a standalone python file",
    "version": "1.4",
    "project_urls": {
        "Homepage": "https://github.com/bulletmark/mutemplate"
    },
    "split_keywords": [
        "micropython",
        " microdot",
        " utemplate"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9279b78941f17f48b7ab0b6657595f7532cd9f1c9649f4fefaddd19043bfceb1",
                "md5": "a282e03915147e0d6deece1b6c5b30c9",
                "sha256": "6050531ccbedf1a3cfcb2f87ddaf785ac5c520140866fa8e19ebd399548e5edc"
            },
            "downloads": -1,
            "filename": "mutemplate-1.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a282e03915147e0d6deece1b6c5b30c9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 11868,
            "upload_time": "2024-12-05T03:29:19",
            "upload_time_iso_8601": "2024-12-05T03:29:19.634033Z",
            "url": "https://files.pythonhosted.org/packages/92/79/b78941f17f48b7ab0b6657595f7532cd9f1c9649f4fefaddd19043bfceb1/mutemplate-1.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "eec3e04a9806e3a01411be4a876148936060e21b1efd16a29c2221dcfe6bcc57",
                "md5": "4f3c77f0eb4fa99d824a3af14074d4aa",
                "sha256": "e67c6542d8ebe207a5d477041711dbdc89cf2b511ff43e6eb8210bc6de2e293f"
            },
            "downloads": -1,
            "filename": "mutemplate-1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "4f3c77f0eb4fa99d824a3af14074d4aa",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 17320,
            "upload_time": "2024-12-05T03:29:21",
            "upload_time_iso_8601": "2024-12-05T03:29:21.534974Z",
            "url": "https://files.pythonhosted.org/packages/ee/c3/e04a9806e3a01411be4a876148936060e21b1efd16a29c2221dcfe6bcc57/mutemplate-1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-05 03:29:21",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "bulletmark",
    "github_project": "mutemplate",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "mutemplate"
}
        
Elapsed time: 0.52943s