Metadata-Version: 2.4
Name: eds4jinja2
Version: 1.0.0
Summary: Embed the data source specifications in your JINJA templates directly, and enjoy the dynamic data contexts.
Author-email: Eugeniu Costetchi <costezki.eugen@gmail.com>
Maintainer-email: Eugeniu Costetchi <costezki.eugen@gmail.com>
License: Apache License 2.0
Project-URL: Homepage, https://github.com/meaningfy-ws/eds4jinja2
Keywords: template,jinja,report,report generation,rdf,sparql,linked-data,data-source,dynamic-context
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Utilities
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Natural Language :: English
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Jinja2~=3.1.2
Requires-Dist: SPARQLWrapper~=2.0.0
Requires-Dist: pandas~=2.2.0
Requires-Dist: PyYAML~=6.0.1
Requires-Dist: toml~=0.10.2
Requires-Dist: xlrd~=2.0.1
Requires-Dist: openpyxl~=3.1.2
Requires-Dist: numpy~=1.26.0
Requires-Dist: click~=8.1.7
Requires-Dist: rdflib~=7.0.0
Requires-Dist: pydantic~=2.0
Requires-Dist: py-singleton~=1.0.0
Requires-Dist: beautifulsoup4~=4.12.2
Requires-Dist: requests~=2.31.0
Provides-Extra: oxigraph
Requires-Dist: pyoxigraph~=0.4; extra == "oxigraph"
Provides-Extra: test
Requires-Dist: tabulate~=0.9.0; extra == "test"
Requires-Dist: coverage~=7.3.2; extra == "test"
Requires-Dist: pytest~=7.4.2; extra == "test"
Requires-Dist: pytest-bdd~=7.0.0; extra == "test"
Requires-Dist: pytest-cov~=4.1.0; extra == "test"
Requires-Dist: pytest-subtests~=0.11.0; extra == "test"
Requires-Dist: flake8~=6.1.0; extra == "test"
Provides-Extra: docs
Requires-Dist: myst-parser~=2.0.0; extra == "docs"
Requires-Dist: Sphinx~=7.1.2; extra == "docs"
Requires-Dist: sphinxcontrib-apidoc~=0.4.0; extra == "docs"
Provides-Extra: dev
Requires-Dist: eds4jinja2[docs,test]; extra == "dev"
Requires-Dist: import-linter~=2.0; extra == "dev"
Requires-Dist: tox~=4.11.3; extra == "dev"
Requires-Dist: tox-pytest-summary~=0.1.2; extra == "dev"
Requires-Dist: build~=1.2; extra == "dev"
Requires-Dist: twine~=6.2; extra == "dev"
Requires-Dist: setuptools~=68.2.2; extra == "dev"
Requires-Dist: wheel~=0.41.2; extra == "dev"
Dynamic: license-file

# eds4jinja2
An easy way to reports generation with Jinja2 templates. 

With Embedded Datasource Specifications inside Jinja2 templates, you can fetch the data you need on the spot. 

![test](https://github.com/meaningfy-ws/eds4jinja2/workflows/test/badge.svg)
[![codecov](https://codecov.io/gh/meaningfy-ws/eds4jinja2/branch/master/graph/badge.svg)](https://codecov.io/gh/meaningfy-ws/eds4jinja2)
[![Documentation Status](https://readthedocs.org/projects/eds4jinja2/badge/?version=latest)](https://eds4jinja2.readthedocs.io/en/latest/?badge=latest)

![PyPI](https://img.shields.io/pypi/v/eds4jinja2?color=teal&label=version)
![PyPI - Status](https://img.shields.io/pypi/status/eds4jinja2)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/eds4jinja2)
![PyPI - License](https://img.shields.io/pypi/l/eds4jinja2?color=green)
![PyPI - Wheel](https://img.shields.io/pypi/wheel/eds4jinja2)

Specify the data sources in your JINJA templates directly.

```jinja2
{% set content, error = from_file(path).fetch_tree() %} \n
content:  {{ content }}\n
error: {{ error }}\n
```

```jinja2
{% set content, error =
    from_endpoint(endpoint).with_query(query_string).fetch_tabular() %}
content:  {{ content }} \n
error: {{ error }} \n
```

# Installation

```shell script
pip install eds4jinja2
```

For the optional fast in-memory SPARQL engine (oxigraph), install the extra:

```shell script
pip install eds4jinja2[oxigraph]
```

# Usage

[Read the docs here](https://eds4jinja2.readthedocs.io/en/latest/)  

## In-memory graph data sources

Besides a remote SPARQL endpoint (`from_endpoint`) and tabular/RDF files, reports can be
rendered against an **in-process RDF graph** — no SPARQL server required. Two builders are
available in templates:

- `from_graph(graph)` — query an in-memory graph/store you already hold (an `rdflib.Graph`,
  a `pyoxigraph` store, or any `query(sparql)` callable). Alias: `from_memory`.
- `from_rdf(sources, engine="rdflib")` — load one or more RDF files/URLs into an in-memory
  graph once (engine: `"rdflib"` default, or `"oxigraph"`) and query it. Both tabular
  (`fetch_tabular`) and tree (`fetch_tree`) results are supported.

To render an **existing report against an in-memory graph with the templates unchanged**,
inject a builder that overrides `from_endpoint` (which the templates already call):

```python
import rdflib
from eds4jinja2 import InMemorySPARQLDataSource
from eds4jinja2.services.report_builder import ReportBuilder

graph = rdflib.Graph().parse("dataset.ttl")  # the consumer owns loading/manipulation
ReportBuilder(
    "report/",
    external_data_source_builders={"from_endpoint": lambda _endpoint: InMemorySPARQLDataSource(graph)},
).make_document()
```

## Parallel report execution

For large reports whose runtime is dominated by SPARQL query latency, set `parallelism` in the
report `config.json` to pre-warm all data fetches concurrently before rendering:

```json
{ "template": "report.html", "conf": {}, "parallelism": 16 }
```

Execution is threads-only and **all-or-nothing** (any fetch failure aborts the report, no
partial output); results are staged in a temp folder that is cleaned up afterwards. With
`parallelism` unset or `1` the behaviour is exactly the previous sequential render. Threaded
speed-up is real for remote endpoints and oxigraph in-memory graphs (both release the GIL);
rdflib in-memory queries are GIL-bound (correct, limited speed-up).

## Contributing
You are more than welcome to help expand and mature this project. We adhere to [Apache code of conduct](https://www.apache.org/foundation/policies/conduct), please follow it in all your interactions on the project.   
When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the maintainers of this repository before making a change.

## Licence 
This project is licensed under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
Powered by [Meaningfy](https://github.com/meaningfy-ws).
