Metadata-Version: 2.4
Name: jug_lca_buildings
Version: 0.1.1
Summary: Embodied and end-of-life estimator service.
Author: Alireza Adli
License:                                  Apache License
                                   Version 2.0, January 2004
                                http://www.apache.org/licenses/
        
           TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
        
           1. Definitions.
        
              "License" shall mean the terms and conditions for use, reproduction,
              and distribution as defined by Sections 1 through 9 of this document.
        
              "Licensor" shall mean the copyright owner or entity authorized by the
              copyright owner that is granting the License.
        
              "Legal Entity" shall mean the union of the acting entity and all other
              entities that control, are controlled by, or are under common control
              with that entity. For the purposes of this definition, "control" means
              (i) the power, direct or indirect, to cause the direction or management
              of such entity, whether by contract or otherwise, or (ii) ownership of
              fifty percent (50%) or more of the outstanding shares, or (iii)
              beneficial ownership of such entity.
        
              "You" (or "Your") shall mean an individual or Legal Entity exercising
              permissions granted by this License.
        
              "Source" form shall mean the preferred form for making modifications,
              including but not limited to software source code, documentation source,
              and configuration files.
        
              "Object" form shall mean any form resulting from mechanical
              transformation or translation of a Source form, including but not
              limited to compiled object code, generated documentation, and
              conversions to other media types.
        
              "Work" shall mean the work of authorship, whether in Source or Object
              form, made available under the License, as indicated by a copyright
              notice that is included in or attached to the work (an example is
              provided in the Appendix below).
        
              "Derivative Works" shall mean any work, whether in Source or Object
              form, that is based on (or derived from) the Work and for which the
              editorial revisions, annotations, elaborations, or other modifications
              represent, as a whole, an original work of authorship. For the purposes
              of this License, Derivative Works shall not include works that remain
              separable from, or merely link (or bind by name) to the interfaces of,
              the Work and Derivative Works thereof.
        
              "Contribution" shall mean any work of authorship, including the
              original version of the Work and any modifications or additions to that
              Work or Derivative Works thereof, that is intentionally submitted to
              Licensor for inclusion in the Work by the copyright owner or by an
              individual or Legal Entity authorized to submit on behalf of the
              copyright owner. For the purposes of this definition, "submitted"
              means any form of electronic, verbal, or written communication sent to
              the Licensor or its representatives, including but not limited to
              communication on electronic mailing lists, source code control systems,
              and issue tracking systems that are managed by, or on behalf of, the
              Licensor for the purpose of discussing and improving the Work, but
              excluding communication that is conspicuously marked or otherwise
              designated in writing by the copyright owner as "Not a Contribution."
        
              "Contributor" shall mean Licensor and any individual or Legal Entity on
              behalf of whom a Contribution has been received by Licensor and
              subsequently incorporated within the Work.
        
           2. Grant of Copyright License. Subject to the terms and conditions of
              this License, each Contributor hereby grants to You a perpetual,
              worldwide, non-exclusive, no-charge, royalty-free, irrevocable
              copyright license to reproduce, prepare Derivative Works of, publicly
              display, publicly perform, sublicense, and distribute the Work and such
              Derivative Works in Source or Object form.
        
           3. Grant of Patent License. Subject to the terms and conditions of this
              License, each Contributor hereby grants to You a perpetual, worldwide,
              non-exclusive, no-charge, royalty-free, irrevocable (except as stated
              in this section) patent license to make, have made, use, offer to sell,
              sell, import, and otherwise transfer the Work, where such license
              applies only to those patent claims licensable by such Contributor that
              are necessarily infringed by their Contribution(s) alone or by
              combination of their Contribution(s) with the Work to which such
              Contribution(s) was submitted. If You institute patent litigation
              against any entity (including a cross-claim or counterclaim in a
              lawsuit) alleging that the Work or a Contribution incorporated within
              the Work constitutes direct or contributory patent infringement, then
              any patent licenses granted to You under this License for that Work
              shall terminate as of the date such litigation is filed.
        
           4. Redistribution. You may reproduce and distribute copies of the Work
              or Derivative Works thereof in any medium, with or without
              modifications, and in Source or Object form, provided that You meet the
              following conditions:
        
              (a) You must give any other recipients of the Work or Derivative Works
                  a copy of this License; and
        
              (b) You must cause any modified files to carry prominent notices stating
                  that You changed the files; and
        
              (c) You must retain, in the Source form of any Derivative Works that You
                  distribute, all copyright, patent, trademark, and attribution
                  notices from the Source form of the Work, excluding those notices
                  that do not pertain to any part of the Derivative Works; and
        
              (d) If the Work includes a "NOTICE" text file as part of its
                  distribution, then any Derivative Works that You distribute must
                  include a readable copy of the attribution notices contained within
                  such NOTICE file, excluding those notices that do not pertain to
                  any part of the Derivative Works, in at least one of the following
                  places: within a NOTICE text file distributed as part of the
                  Derivative Works; within the Source form or documentation, if
                  provided along with the Derivative Works; or, within a display
                  generated by the Derivative Works, if and wherever such third-party
                  notices normally appear. The contents of the NOTICE file are for
                  informational purposes only and do not modify the License. You may
                  add Your own attribution notices within Derivative Works that You
                  distribute, alongside or as an addendum to the NOTICE text from the
                  Work, provided that such additional attribution notices cannot be
                  construed as modifying the License.
        
              You may add Your own copyright statement to Your modifications and may
              provide additional or different license terms and conditions for use,
              reproduction, or distribution of Your modifications, or for any such
              Derivative Works as a whole, provided Your use, reproduction, and
              distribution of the Work otherwise complies with the conditions stated
              in this License.
        
           5. Submission of Contributions. Unless You explicitly state otherwise,
              any Contribution intentionally submitted for inclusion in the Work by
              You to the Licensor shall be under the terms and conditions of this
              License, without any additional terms or conditions. Notwithstanding
              the above, nothing herein shall supersede or modify the terms of any
              separate license agreement you may have executed with Licensor
              regarding such Contributions.
        
           6. Trademarks. This License does not grant permission to use the trade
              names, trademarks, service marks, or product names of the Licensor,
              except as required for reasonable and customary use in describing the
              origin of the Work and reproducing the content of the NOTICE file.
        
           7. Disclaimer of Warranty. Unless required by applicable law or agreed to
              in writing, Licensor provides the Work (and each Contributor provides
              its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR
              CONDITIONS OF ANY KIND, either express or implied, including, without
              limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
              MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely
              responsible for determining the appropriateness of using or
              redistributing the Work and assume any risks associated with Your
              exercise of permissions under this License.
        
           8. Limitation of Liability. In no event and under no legal theory,
              whether in tort (including negligence), contract, or otherwise, unless
              required by applicable law (such as deliberate and grossly negligent
              acts) or agreed to in writing, shall any Contributor be liable to You
              for damages, including any direct, indirect, special, incidental, or
              consequential damages of any character arising as a result of this
              License or out of the use or inability to use the Work (including but
              not limited to damages for loss of goodwill, work stoppage, computer
              failure or malfunction, or any and all other commercial damages or
              losses), even if such Contributor has been advised of the possibility
              of such damages.
        
           9. Accepting Warranty or Additional Liability. While redistributing the
              Work or Derivative Works thereof, You may choose to offer, and charge a
              fee for, acceptance of support, warranty, indemnity, or other liability
              obligations and/or rights consistent with this License. However, in
              accepting such obligations, You may act only on Your own behalf and on
              Your sole responsibility, not on behalf of any other Contributor, and
              only if You agree to indemnify, defend, and hold each Contributor
              harmless for any liability incurred by, or claims asserted against,
              such Contributor by reason of your accepting any such warranty or
              additional liability.
        
           END OF TERMS AND CONDITIONS
        
           Copyright 2026 Alireza Adli
        
           Licensed under the Apache License, Version 2.0 (the "License");
           you may not use this file except in compliance with the License.
           You may obtain a copy of the License at
        
               http://www.apache.org/licenses/LICENSE-2.0
        
           Unless required by applicable law or agreed to in writing, software
           distributed under the License is distributed on an "AS IS" BASIS,
           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           See the License for the specific language governing permissions and
           limitations under the License.
        
Project-URL: Homepage, https://demianadli.com
Project-URL: Repository, https://github.com/demianAdli/sabu
Project-URL: Source, https://github.com/demianAdli/sabu/tree/main/services/jug_lca_buildings
Project-URL: Issues, https://github.com/demianAdli/sabu/issues
Project-URL: Changelog, https://github.com/demianAdli/sabu/tree/main/services/jug_lca_buildings/CHANGELOG.md
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cerc-hub==0.2.0.8
Requires-Dist: flask==3.1.1
Requires-Dist: flask-smorest==0.46.1
Requires-Dist: sabu-chassis==0.1.0
Dynamic: license-file

# JUG LCA Buildings

`jug_lca_buildings` is a Sabu microservice that estimates building-level life-cycle carbon emissions from GeoJSON building data.

At a high level, the service accepts a GeoJSON `FeatureCollection` of buildings, runs a building life-cycle assessment workflow, and returns emissions results for the embodied and end-of-life stages. It can return either JSON results for API-to-API use or a CSV report for download and review.

All emission values returned by this service are expressed as `kgCO2e` per building unless stated otherwise.

This service is part of the broader Sabu project, where each "jug" is a focused microservice for a specific urban carbon or geospatial workflow. In that architecture, `jug_lca_buildings` covers the building LCA calculation step.

## What The Service Does

- Accepts building data through `POST /emissions` as JSON or `POST /emissions/upload` as a GeoJSON file upload.
- Validates the request structure before running the workflow.
- Calculates embodied and end-of-life emissions for each building.
- Can export results as JSON or as a CSV report with per-building rows and totals.
- Stores generated artifacts under `.runtime/jug_lca_buildings` unless `JUG_LCA_ARTIFACTS_DIR` is set.

## Units

- `opening_embodied_emissions`, `envelope_embodied_emissions`, and `component_embodied_emissions` are reported in `kgCO2e`.
- `opening_end_of_life_emissions`, `envelope_end_of_life_emissions`, and `component_end_of_life_emissions` are reported in `kgCO2e`.
- CSV totals such as `total_embodied_emissions`, `total_end_of_life_emissions`, and `total_lca_emissions` are also reported in `kgCO2e`.
- These values are absolute totals for each building, not per-square-metre intensities and not tonnes.

## Inputs Needed For Testing

For a basic test request, you need a GeoJSON `FeatureCollection` where each feature represents one building and includes:

- `type`
- `id`
- `geometry`
- `properties.name`
- `properties.address`
- `properties.function`
- `properties.height`
- `properties.year_of_construction`

The service also depends on bundled reference data used by the workflow:

- [`src/jug_lca_buildings/data/nrcan_archetypes.json`](src/jug_lca_buildings/data/nrcan_archetypes.json)
- [`src/jug_lca_buildings/data/nrcan_constructions_cap_3.json`](src/jug_lca_buildings/data/nrcan_constructions_cap_3.json)
- [`src/jug_lca_buildings/data/nrcan_materials_dictionaries.json`](src/jug_lca_buildings/data/nrcan_materials_dictionaries.json)
- [`src/jug_lca_buildings/data/nrcan_transparent_surfaces_dictionaries.json`](src/jug_lca_buildings/data/nrcan_transparent_surfaces_dictionaries.json)

## Example Test Data

Contract examples already exist in the repository and are the safest starting point for manual or integration testing:

- [`contracts/examples/jug_lca_buildings/README.md`](../../contracts/examples/jug_lca_buildings/README.md)
- [`contracts/openapi/jug_lca_buildings.yaml`](../../contracts/openapi/jug_lca_buildings.yaml)
- External examples repository: <https://github.com/demianAdli/sabu-test-data-and-examples/tree/main/services/jug_lca_buildings>

The contract examples include:

- an example JSON body for `POST /emissions`
- an example JSON success response
- an example CSV export response
- example error payloads for invalid upload and validation failures

The test suite also shows the minimum valid request shape used in automated tests:

- [`tests/test_emissions_api.py`](tests/test_emissions_api.py)

That minimum test payload is a single polygon building with basic metadata such as name, address, function, height, and year of construction.

## Running A Simple Test

Once the service is running locally, you can test it by:

1. Sending a JSON GeoJSON payload to `POST /emissions`.
2. Sending the same payload with `?export=csv` to download a CSV report.
3. Uploading a `.geojson` file to `POST /emissions/upload`.

## External Test Data Reference

Additional example inputs and supporting test data are also available in the external repository:

<https://github.com/demianAdli/sabu-test-data-and-examples/tree/main/services/jug_lca_buildings>

Use that repository together with the local contract artifacts in this project when preparing manual tests or integration examples.

## Usage Examples

Instructions on how to run `jug_lca_buildings` in different settings can be found in these example directories:

- API usage: <https://github.com/demianAdli/sabu-test-data-and-examples/tree/main/services/jug_lca_buildings/examples/api>
- Direct Python run: <https://github.com/demianAdli/sabu-test-data-and-examples/tree/main/services/jug_lca_buildings/examples/direct-python>
- Docker Compose run: <https://github.com/demianAdli/sabu-test-data-and-examples/tree/main/services/jug_lca_buildings/examples/docker>

## Docker Image

The container image is intended to run the published PyPI package, not the local checkout.

- Runtime port inside the container: `5000`
- Recommended host mapping: `-p 8080:5000` or any other host port you prefer
- Image tag should match the package version, for example `0.1.1`
- Do not publish `latest`; only publish versioned tags
- Build args `JUG_LCA_BUILDINGS_VERSION` and `SABU_CHASSIS_VERSION` are optional and default to `latest`
- If a package version build arg is omitted or set to `latest`, Docker installs the latest available release from PyPI
- If a package version build arg is provided, Docker pins that package to the exact version

Example build and run commands using the latest PyPI releases:

```bash
docker build \
  --no-cache \
  -f services/jug_lca_buildings/docker/Dockerfile \
  -t demianadli/jug_lca_buildings:0.1.1 \
  .

docker run --rm \
  -p 8080:5000 \
  -e JUG_LCA_ARTIFACTS_DIR=/app/data/jug_lca_buildings \
  demianadli/jug_lca_buildings:0.1.1
```

Example pinned build:

```bash
docker build \
  -f services/jug_lca_buildings/docker/Dockerfile \
  --build-arg JUG_LCA_BUILDINGS_VERSION=0.1.1 \
  --build-arg SABU_CHASSIS_VERSION=0.1.0 \
  -t demianadli/jug_lca_buildings:0.1.1 \
  .
```

Compose example:

```bash
docker compose -f services/jug_lca_buildings/docker-compose.yml build --no-cache
docker compose -f services/jug_lca_buildings/docker-compose.yml up -d
```

The compose file can build the image locally from the Dockerfile. By default it installs the latest available PyPI releases for `jug_lca_buildings` and `sabu-chassis`, so you can rebuild locally after publishing either package to PyPI without publishing a new Docker Hub image. Use `--no-cache` when you want Docker to check PyPI again instead of reusing the previous pip-install layer.

To pin versions in Compose, set environment variables before building:

```bash
JUG_LCA_BUILDINGS_VERSION=0.1.1 SABU_CHASSIS_VERSION=0.1.0 \
  docker compose -f services/jug_lca_buildings/docker-compose.yml up -d --build
```

## Versioned Publishing

The GitHub Actions workflow publishes the image from a version tag only.

- Tag format: `jug_lca_buildings-v0.1.1`
- Docker Hub image tag: `0.1.1`
- Workflow file: [`.github/workflows/publish-jug-lca-buildings-docker.yml`](../../.github/workflows/publish-jug-lca-buildings-docker.yml)

Release flow:

1. Publish `jug_lca_buildings==0.1.1` to PyPI.
2. Create and push the git tag `jug_lca_buildings-v0.1.1`.
3. GitHub Actions builds the Docker image with `JUG_LCA_BUILDINGS_VERSION=0.1.1`.
4. The image is pushed to Docker Hub as `demianadli/jug_lca_buildings:0.1.1`.
