{"id":25856949,"url":"https://github.com/m42e/httypist","last_synced_at":"2025-06-27T05:34:32.083Z","repository":{"id":49713280,"uuid":"223897418","full_name":"m42e/httypist","owner":"m42e","description":"A document generator, triggered by callbacks","archived":false,"fork":false,"pushed_at":"2022-12-08T10:55:07.000Z","size":74,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-23T19:16:25.787Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m42e.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-25T08:23:52.000Z","updated_at":"2023-08-22T23:02:18.000Z","dependencies_parsed_at":"2023-01-25T11:45:59.468Z","dependency_job_id":null,"html_url":"https://github.com/m42e/httypist","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m42e%2Fhttypist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m42e%2Fhttypist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m42e%2Fhttypist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m42e%2Fhttypist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m42e","download_url":"https://codeload.github.com/m42e/httypist/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241407293,"owners_count":19958103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-01T18:29:28.402Z","updated_at":"2025-03-01T18:29:29.419Z","avatar_url":"https://github.com/m42e.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Document automation\n\nThis is actually getting useful.\n\n## Use of this\n\nIt is a http typist so a httypist. It should generate document for you in a known environment (docker container) and could be triggered via http. And the configuration and templates should be in a git repository.\n\n## Targets\n\n- HTTP Hooks a triggers\n- HTTP Callbacks for the result \n- GIT Repository with the templates\n- Template selection by \n  - url or \n  - data in the request\n- PDF output using latex (you have to use a docker image as base for the worker, which has latex installed)\n- Use template folders, including all the auxiliary files for the template\n- No need to update the docker containers in case of a template update\n- Simple mechanism for authentication\n\n\n## Implementation\n\n- Python fastapi http handler\n- Ninja2 Template engine (for your templates)\n- xelatex for the LaTeX processing (if you wish and need)\n- rq for the background generation of documents\n- docker container for easy deployment\n\n## Issues to think about\n\n- At the moment the update and the generation are not protected against each other, so generation may fail when an update is started at the same time which e.g. deletes the template.\n- It is single user design at the moment. So you can configure only one repo as source for all the templates.\n- The template source is restricted to folders. Templates in subfolders are not supported.\n- It is an optimistic implementation\n\n\n## Usage\n\n### 1. Create a repository with templates\n\nCreate a git repository with templates you want to use. Each template requires:\n\n- a own folder\n- file(s) with the extension `.jinja`\n- a config file `config.yml`\n\nAll files, with the ending `.jinja` will be processed as template. This means you can keep some structure for your documents. \nThe template folder could have a separate file named `config.yml` which could set the options for the selection of this template and additional options passed to the processor.\n\n### Data available\n\nIn the evaluation of the selector (which is expected to be a jinja template) and the document template the following data is available:\n\n- **json**: The bodies content (if it is json) already parsed.\n- **body**: The raw body content\n- **headers**: All the headers as dict.\n- **query**: The query parameters as dict.\n- **client**: The client host.\n\n### config.yml\n\nThis is an example file:\n\n```\nselector:\n  - json.custom_text_value1 == \"ThisFile\" \nfiletypes:\n  tex:\n    jinja:\n      block_start_string: '\\BLOCK{'\n      block_end_string: '}'\n      variable_start_string: '\\VAR{'\n      variable_end_string: '}'\n      comment_start_string: '\\#{'\n      comment_end_string: '}'\n      line_statement_prefix: '%%'\n      line_comment_prefix: '%#'\npost:\n  xelatex:\n    - latexmk\n    - -pdf\n    - -pdflatex=xelatex -no-shell-escape -halt-on-error -interaction=batchmode %O %S\ncallback:\n  method: post\n  template: https://testapi.d1v3.de/index.php?test=hallo\u0026hallo={{ args['wer'] }}\n  data: \n    - name: vertrag.pdf\n      binary: true\naccess:\n  - \"sometokenyoucanchoose\"\n```\nThe `selector` selects the matching template based on the data provided. This enables to have a folder structure besides the selection mechanism and reuse templates.\n\nThe `filetypes` block is used to configure the jinja2 Environment. This is configurable per filetype.\n\nIn the `post` section you could define commands (with parameters) that should be run, after the template replacement took place.\n\nThe final `callback` does exactly what the name suggests, it performs a callback to the url (which is also a template and can use the data from the request). It could include data.\n\nUnder the `access` key you can list some strings which act as tokens required in the authentication header to generate the document.\n\n\n### Docker\n\nThere are two docker containers, one is for the frontend, taking the requests, the other one is for the worker, actually doing the real work.\nIt is utilizing redis for the job and result. See the [docker-compose.yml](docker/docker-compose.yml) for details\n\nYou start the docker container with a set of environment variables, such as:\n\n```\nGIT_REPO=somehost:your/repo\n```\n\nThis will clone the git repository containing the templates and configuration. There will also be an URL for updating the repository (`/update`), so webhooks for the repository work fine.\n\nYou add a folder to the repository, containing a file like this:\n\n`test.jinja`\n```\nHello {{ data['client']['name'] }}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm42e%2Fhttypist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm42e%2Fhttypist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm42e%2Fhttypist/lists"}