infrared-sdk 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrared_sdk-0.4.0/.env.example +2 -0
- infrared_sdk-0.4.0/.github/CODEOWNERS +1 -0
- infrared_sdk-0.4.0/.github/ISSUE_TEMPLATE/bug_report.yml +54 -0
- infrared_sdk-0.4.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- infrared_sdk-0.4.0/.github/ISSUE_TEMPLATE/feature_request.yml +25 -0
- infrared_sdk-0.4.0/.github/PULL_REQUEST_TEMPLATE.md +10 -0
- infrared_sdk-0.4.0/.github/workflows/ci.yml +42 -0
- infrared_sdk-0.4.0/.github/workflows/publish.yml +21 -0
- infrared_sdk-0.4.0/.github/workflows/pypi-publish.yml +50 -0
- infrared_sdk-0.4.0/.github/workflows/pypi-test-publish.yml +49 -0
- infrared_sdk-0.4.0/.gitignore +234 -0
- infrared_sdk-0.4.0/.pre-commit-config.yaml +18 -0
- infrared_sdk-0.4.0/.vscode/settings.json +14 -0
- infrared_sdk-0.4.0/CHANGELOG.md +93 -0
- infrared_sdk-0.4.0/CLAUDE.md +180 -0
- infrared_sdk-0.4.0/CODE_OF_CONDUCT.md +13 -0
- infrared_sdk-0.4.0/LICENSE +201 -0
- infrared_sdk-0.4.0/NOTICE +5 -0
- infrared_sdk-0.4.0/PKG-INFO +1107 -0
- infrared_sdk-0.4.0/README.md +1093 -0
- infrared_sdk-0.4.0/SECURITY.md +22 -0
- infrared_sdk-0.4.0/assets/logo-teal.svg +1 -0
- infrared_sdk-0.4.0/assets/per_tile_coordinate_transform_standalone.svg +94 -0
- infrared_sdk-0.4.0/assets/polygon_bbox_sw_frame_standalone.svg +69 -0
- infrared_sdk-0.4.0/assets/solar_tiling_diagram_standalone.svg +58 -0
- infrared_sdk-0.4.0/assets/time_period_filter_diagram_standalone.svg +87 -0
- infrared_sdk-0.4.0/assets/wind_tiling_diagram_standalone.svg +63 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/.env.example +17 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/README.md +191 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/db.py +496 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/generate_visualizations.py +269 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/requirements.txt +5 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/submit_analyses.py +590 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/visualize.py +563 -0
- infrared_sdk-0.4.0/demos/areas_demo_async/webhook_server.py +205 -0
- infrared_sdk-0.4.0/demos/demo_advanced_usage.py +527 -0
- infrared_sdk-0.4.0/demos/demo_fetch_layers.py +166 -0
- infrared_sdk-0.4.0/demos/demo_tiling.py +134 -0
- infrared_sdk-0.4.0/demos/demo_utci_analysis.py +147 -0
- infrared_sdk-0.4.0/demos/demo_vegetation_ground.py +130 -0
- infrared_sdk-0.4.0/demos/demo_vienna.py +464 -0
- infrared_sdk-0.4.0/demos/demo_wind_analysis.py +110 -0
- infrared_sdk-0.4.0/public-demos/.env.example +9 -0
- infrared_sdk-0.4.0/public-demos/00_quickstart.ipynb +269 -0
- infrared_sdk-0.4.0/public-demos/01_buildings.ipynb +338 -0
- infrared_sdk-0.4.0/public-demos/02_vegetation_and_ground.ipynb +313 -0
- infrared_sdk-0.4.0/public-demos/03_weather_and_time_periods.ipynb +289 -0
- infrared_sdk-0.4.0/public-demos/04_tiling_and_area_api.ipynb +416 -0
- infrared_sdk-0.4.0/public-demos/05_analysis_types_tour.ipynb +504 -0
- infrared_sdk-0.4.0/public-demos/06_image_rendering.ipynb +333 -0
- infrared_sdk-0.4.0/public-demos/07_async_and_webhooks.ipynb +302 -0
- infrared_sdk-0.4.0/public-demos/README.md +93 -0
- infrared_sdk-0.4.0/public-demos/cities.py +135 -0
- infrared_sdk-0.4.0/public-demos/requirements.txt +11 -0
- infrared_sdk-0.4.0/public-demos/webhook_receiver.py +155 -0
- infrared_sdk-0.4.0/pyproject.toml +57 -0
- infrared_sdk-0.4.0/skills/async-jobs.md +297 -0
- infrared_sdk-0.4.0/skills/infrared-async-api-guide.md +313 -0
- infrared_sdk-0.4.0/skills/infrared-sdk-agents/SKILL.md +253 -0
- infrared_sdk-0.4.0/skills/infrared-sdk-consumers/SKILL.md +174 -0
- infrared_sdk-0.4.0/skills/infrared-sdk-contributors/SKILL.md +284 -0
- infrared_sdk-0.4.0/src/infrared_sdk/__init__.py +139 -0
- infrared_sdk-0.4.0/src/infrared_sdk/_area/__init__.py +0 -0
- infrared_sdk-0.4.0/src/infrared_sdk/_area/_layers.py +78 -0
- infrared_sdk-0.4.0/src/infrared_sdk/_area/_merging.py +337 -0
- infrared_sdk-0.4.0/src/infrared_sdk/_area/_polling.py +146 -0
- infrared_sdk-0.4.0/src/infrared_sdk/_area/_submission.py +414 -0
- infrared_sdk-0.4.0/src/infrared_sdk/_area/_thread_clients.py +56 -0
- infrared_sdk-0.4.0/src/infrared_sdk/analyses/__init__.py +34 -0
- infrared_sdk-0.4.0/src/infrared_sdk/analyses/jobs.py +628 -0
- infrared_sdk-0.4.0/src/infrared_sdk/analyses/service.py +90 -0
- infrared_sdk-0.4.0/src/infrared_sdk/analyses/types.py +473 -0
- infrared_sdk-0.4.0/src/infrared_sdk/buildings/__init__.py +18 -0
- infrared_sdk-0.4.0/src/infrared_sdk/buildings/service.py +577 -0
- infrared_sdk-0.4.0/src/infrared_sdk/buildings/types.py +205 -0
- infrared_sdk-0.4.0/src/infrared_sdk/ground_materials/__init__.py +9 -0
- infrared_sdk-0.4.0/src/infrared_sdk/ground_materials/dedup.py +223 -0
- infrared_sdk-0.4.0/src/infrared_sdk/ground_materials/service.py +369 -0
- infrared_sdk-0.4.0/src/infrared_sdk/ground_materials/types.py +24 -0
- infrared_sdk-0.4.0/src/infrared_sdk/layers/__init__.py +7 -0
- infrared_sdk-0.4.0/src/infrared_sdk/layers/service.py +219 -0
- infrared_sdk-0.4.0/src/infrared_sdk/models.py +228 -0
- infrared_sdk-0.4.0/src/infrared_sdk/preflight/__init__.py +27 -0
- infrared_sdk-0.4.0/src/infrared_sdk/preflight/sun_context.py +525 -0
- infrared_sdk-0.4.0/src/infrared_sdk/py.typed +0 -0
- infrared_sdk-0.4.0/src/infrared_sdk/sdk.py +641 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/__init__.py +25 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/config.py +121 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/executor.py +521 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/merger.py +282 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/orchestrator.py +94 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/tiles.py +466 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/transforms.py +291 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/types.py +732 -0
- infrared_sdk-0.4.0/src/infrared_sdk/tiling/validation.py +274 -0
- infrared_sdk-0.4.0/src/infrared_sdk/vegetation/__init__.py +14 -0
- infrared_sdk-0.4.0/src/infrared_sdk/vegetation/dedup.py +161 -0
- infrared_sdk-0.4.0/src/infrared_sdk/vegetation/service.py +284 -0
- infrared_sdk-0.4.0/src/infrared_sdk/vegetation/types.py +23 -0
- infrared_sdk-0.4.0/src/infrared_sdk/webhooks/NOTE.md +18 -0
- infrared_sdk-0.4.0/src/infrared_sdk/webhooks/__init__.py +28 -0
- infrared_sdk-0.4.0/src/infrared_sdk/webhooks/service.py +356 -0
- infrared_sdk-0.4.0/src/infrared_sdk/webhooks/types.py +112 -0
- infrared_sdk-0.4.0/tests/__init__.py +0 -0
- infrared_sdk-0.4.0/tests/analyses/__init__.py +0 -0
- infrared_sdk-0.4.0/tests/analyses/test_analyses.py +829 -0
- infrared_sdk-0.4.0/tests/analyses/test_analyses_client.py +288 -0
- infrared_sdk-0.4.0/tests/analyses/test_jobs.py +1041 -0
- infrared_sdk-0.4.0/tests/area_benchmark.py +604 -0
- infrared_sdk-0.4.0/tests/buildings/__init__.py +0 -0
- infrared_sdk-0.4.0/tests/buildings/test_buildings.py +232 -0
- infrared_sdk-0.4.0/tests/buildings/test_buildings_area.py +1016 -0
- infrared_sdk-0.4.0/tests/buildings/test_buildings_client.py +204 -0
- infrared_sdk-0.4.0/tests/buildings/test_buildings_tiled.py +603 -0
- infrared_sdk-0.4.0/tests/fixtures/buildings_api_response.json +25 -0
- infrared_sdk-0.4.0/tests/fixtures/sample_geometry.json +59416 -0
- infrared_sdk-0.4.0/tests/layers/__init__.py +0 -0
- infrared_sdk-0.4.0/tests/layers/test_ground_materials.py +245 -0
- infrared_sdk-0.4.0/tests/layers/test_vegetation.py +243 -0
- infrared_sdk-0.4.0/tests/layers/test_weather_client.py +95 -0
- infrared_sdk-0.4.0/tests/models/__init__.py +0 -0
- infrared_sdk-0.4.0/tests/models/test_utils.py +239 -0
- infrared_sdk-0.4.0/tests/preflight/__init__.py +0 -0
- infrared_sdk-0.4.0/tests/preflight/test_sun_context.py +615 -0
- infrared_sdk-0.4.0/tests/test_run_area.py +1714 -0
- infrared_sdk-0.4.0/tests/test_types.py +559 -0
- infrared_sdk-0.4.0/tests/test_webhooks.py +466 -0
- infrared_sdk-0.4.0/tests/tile_benchmark.py +591 -0
- infrared_sdk-0.4.0/tests/tiling/__init__.py +0 -0
- infrared_sdk-0.4.0/tests/tiling/test_composable.py +35 -0
- infrared_sdk-0.4.0/tests/tiling/test_executor.py +926 -0
- infrared_sdk-0.4.0/tests/tiling/test_generate_tiles.py +200 -0
- infrared_sdk-0.4.0/tests/tiling/test_merger.py +431 -0
- infrared_sdk-0.4.0/tests/tiling/test_orchestrator.py +706 -0
- infrared_sdk-0.4.0/tests/tiling/test_tiles.py +612 -0
- infrared_sdk-0.4.0/tests/tiling/test_transforms.py +587 -0
- infrared_sdk-0.4.0/tests/tiling/test_types.py +267 -0
- infrared_sdk-0.4.0/tests/tiling/test_validation.py +271 -0
- infrared_sdk-0.4.0/uv.lock +556 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @Infrared-city/sdk-maintainers
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug in the Infrared SDK
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: input
|
|
6
|
+
id: sdk-version
|
|
7
|
+
attributes:
|
|
8
|
+
label: SDK Version
|
|
9
|
+
placeholder: "0.2.0"
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: input
|
|
13
|
+
id: python-version
|
|
14
|
+
attributes:
|
|
15
|
+
label: Python Version
|
|
16
|
+
placeholder: "3.12"
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: input
|
|
20
|
+
id: os
|
|
21
|
+
attributes:
|
|
22
|
+
label: Operating System
|
|
23
|
+
placeholder: "macOS 15, Ubuntu 24.04, Windows 11"
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
- type: textarea
|
|
27
|
+
id: description
|
|
28
|
+
attributes:
|
|
29
|
+
label: Description
|
|
30
|
+
description: What happened?
|
|
31
|
+
validations:
|
|
32
|
+
required: true
|
|
33
|
+
- type: textarea
|
|
34
|
+
id: steps
|
|
35
|
+
attributes:
|
|
36
|
+
label: Steps to Reproduce
|
|
37
|
+
description: Minimal code or steps to reproduce the issue.
|
|
38
|
+
render: python
|
|
39
|
+
validations:
|
|
40
|
+
required: true
|
|
41
|
+
- type: textarea
|
|
42
|
+
id: expected
|
|
43
|
+
attributes:
|
|
44
|
+
label: Expected Behavior
|
|
45
|
+
description: What did you expect to happen?
|
|
46
|
+
validations:
|
|
47
|
+
required: true
|
|
48
|
+
- type: textarea
|
|
49
|
+
id: actual
|
|
50
|
+
attributes:
|
|
51
|
+
label: Actual Behavior
|
|
52
|
+
description: What actually happened? Include error messages or tracebacks.
|
|
53
|
+
validations:
|
|
54
|
+
required: true
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature or improvement
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: use-case
|
|
7
|
+
attributes:
|
|
8
|
+
label: Use Case
|
|
9
|
+
description: What problem are you trying to solve?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: proposed-solution
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed Solution
|
|
16
|
+
description: How would you like this to work?
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: alternatives
|
|
21
|
+
attributes:
|
|
22
|
+
label: Alternatives Considered
|
|
23
|
+
description: What workarounds or alternatives have you tried?
|
|
24
|
+
validations:
|
|
25
|
+
required: false
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: astral-sh/setup-uv@v4
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- run: uv sync --group dev
|
|
21
|
+
- run: uv run pytest --cov=infrared_sdk -v
|
|
22
|
+
|
|
23
|
+
lint:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: astral-sh/setup-uv@v4
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.13"
|
|
30
|
+
- run: uv sync --group dev
|
|
31
|
+
- run: uv run ruff check .
|
|
32
|
+
- run: uv run ruff format --check .
|
|
33
|
+
|
|
34
|
+
typecheck:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: astral-sh/setup-uv@v4
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.13"
|
|
41
|
+
- run: uv sync --group dev
|
|
42
|
+
- run: uv run pyright src/infrared_sdk/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: pypi
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: astral-sh/setup-uv@v4
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.13"
|
|
20
|
+
- run: uv build
|
|
21
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Upload to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release-build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v6
|
|
17
|
+
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v8.0.0
|
|
20
|
+
|
|
21
|
+
- name: Build release distributions
|
|
22
|
+
run: uv build
|
|
23
|
+
|
|
24
|
+
- name: Upload distributions
|
|
25
|
+
uses: actions/upload-artifact@v7
|
|
26
|
+
with:
|
|
27
|
+
name: release-dists
|
|
28
|
+
path: dist/
|
|
29
|
+
|
|
30
|
+
pypi-publish:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
needs:
|
|
33
|
+
- release-build
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
|
|
37
|
+
environment:
|
|
38
|
+
name: pypi
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- name: Retrieve release distributions
|
|
42
|
+
uses: actions/download-artifact@v8
|
|
43
|
+
with:
|
|
44
|
+
name: release-dists
|
|
45
|
+
path: dist/
|
|
46
|
+
|
|
47
|
+
- name: Publish release distributions to PyPI
|
|
48
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
49
|
+
with:
|
|
50
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Upload to TestPyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
release-build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v8.0.0
|
|
18
|
+
|
|
19
|
+
- name: Build release distributions
|
|
20
|
+
run: uv build
|
|
21
|
+
|
|
22
|
+
- name: Upload distributions
|
|
23
|
+
uses: actions/upload-artifact@v7
|
|
24
|
+
with:
|
|
25
|
+
name: release-dists
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
testpypi-publish:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
needs:
|
|
31
|
+
- release-build
|
|
32
|
+
permissions:
|
|
33
|
+
id-token: write
|
|
34
|
+
|
|
35
|
+
environment:
|
|
36
|
+
name: testpypi
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- name: Retrieve release distributions
|
|
40
|
+
uses: actions/download-artifact@v8
|
|
41
|
+
with:
|
|
42
|
+
name: release-dists
|
|
43
|
+
path: dist/
|
|
44
|
+
|
|
45
|
+
- name: Publish release distributions to TestPyPI
|
|
46
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
47
|
+
with:
|
|
48
|
+
repository-url: https://test.pypi.org/legacy/
|
|
49
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Created by https://gitignore.org
|
|
2
|
+
# Python.gitignore
|
|
3
|
+
|
|
4
|
+
# Byte-compiled / optimized / DLL files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[codz]
|
|
7
|
+
*$py.class
|
|
8
|
+
|
|
9
|
+
# C extensions
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
.flow
|
|
13
|
+
.claude
|
|
14
|
+
|
|
15
|
+
# Distribution / packaging
|
|
16
|
+
.Python
|
|
17
|
+
build/
|
|
18
|
+
develop-eggs/
|
|
19
|
+
dist/
|
|
20
|
+
downloads/
|
|
21
|
+
eggs/
|
|
22
|
+
.eggs/
|
|
23
|
+
lib/
|
|
24
|
+
lib64/
|
|
25
|
+
parts/
|
|
26
|
+
sdist/
|
|
27
|
+
var/
|
|
28
|
+
wheels/
|
|
29
|
+
share/python-wheels/
|
|
30
|
+
*.egg-info/
|
|
31
|
+
.installed.cfg
|
|
32
|
+
*.egg
|
|
33
|
+
MANIFEST
|
|
34
|
+
|
|
35
|
+
# PyInstaller
|
|
36
|
+
# Usually these files are written by a python script from a template
|
|
37
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
38
|
+
*.manifest
|
|
39
|
+
*.spec
|
|
40
|
+
|
|
41
|
+
# Installer logs
|
|
42
|
+
pip-log.txt
|
|
43
|
+
pip-delete-this-directory.txt
|
|
44
|
+
|
|
45
|
+
# Unit test / coverage reports
|
|
46
|
+
htmlcov/
|
|
47
|
+
.tox/
|
|
48
|
+
.nox/
|
|
49
|
+
.coverage
|
|
50
|
+
.coverage.*
|
|
51
|
+
.cache
|
|
52
|
+
cache
|
|
53
|
+
nosetests.xml
|
|
54
|
+
coverage.xml
|
|
55
|
+
*.cover
|
|
56
|
+
*.py.cover
|
|
57
|
+
.hypothesis/
|
|
58
|
+
.pytest_cache/
|
|
59
|
+
cover/
|
|
60
|
+
|
|
61
|
+
# Translations
|
|
62
|
+
*.mo
|
|
63
|
+
*.pot
|
|
64
|
+
|
|
65
|
+
# Django stuff:
|
|
66
|
+
*.log
|
|
67
|
+
local_settings.py
|
|
68
|
+
db.sqlite3
|
|
69
|
+
db.sqlite3-journal
|
|
70
|
+
|
|
71
|
+
# Flask stuff:
|
|
72
|
+
instance/
|
|
73
|
+
.webassets-cache
|
|
74
|
+
|
|
75
|
+
# Scrapy stuff:
|
|
76
|
+
.scrapy
|
|
77
|
+
|
|
78
|
+
# Sphinx documentation
|
|
79
|
+
docs/_build/
|
|
80
|
+
|
|
81
|
+
# PyBuilder
|
|
82
|
+
.pybuilder/
|
|
83
|
+
target/
|
|
84
|
+
|
|
85
|
+
# Jupyter Notebook
|
|
86
|
+
.ipynb_checkpoints
|
|
87
|
+
|
|
88
|
+
# IPython
|
|
89
|
+
profile_default/
|
|
90
|
+
ipython_config.py
|
|
91
|
+
model_payloads/*
|
|
92
|
+
|
|
93
|
+
# pyenv
|
|
94
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
95
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
96
|
+
# .python-version
|
|
97
|
+
|
|
98
|
+
# pipenv
|
|
99
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
100
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
101
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
102
|
+
# install all needed dependencies.
|
|
103
|
+
# Pipfile.lock
|
|
104
|
+
|
|
105
|
+
# UV
|
|
106
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
107
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
108
|
+
# commonly ignored for libraries.
|
|
109
|
+
# uv.lock
|
|
110
|
+
|
|
111
|
+
# poetry
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
113
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
114
|
+
# commonly ignored for libraries.
|
|
115
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
116
|
+
# poetry.lock
|
|
117
|
+
# poetry.toml
|
|
118
|
+
|
|
119
|
+
# pdm
|
|
120
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
121
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
122
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
123
|
+
# pdm.lock
|
|
124
|
+
# pdm.toml
|
|
125
|
+
.pdm-python
|
|
126
|
+
.pdm-build/
|
|
127
|
+
|
|
128
|
+
# pixi
|
|
129
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
130
|
+
# pixi.lock
|
|
131
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
132
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
133
|
+
.pixi
|
|
134
|
+
|
|
135
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
136
|
+
__pypackages__/
|
|
137
|
+
|
|
138
|
+
# Celery stuff
|
|
139
|
+
celerybeat-schedule
|
|
140
|
+
celerybeat.pid
|
|
141
|
+
|
|
142
|
+
# Redis
|
|
143
|
+
*.rdb
|
|
144
|
+
*.aof
|
|
145
|
+
*.pid
|
|
146
|
+
|
|
147
|
+
# RabbitMQ
|
|
148
|
+
mnesia/
|
|
149
|
+
rabbitmq/
|
|
150
|
+
rabbitmq-data/
|
|
151
|
+
|
|
152
|
+
# ActiveMQ
|
|
153
|
+
activemq-data/
|
|
154
|
+
|
|
155
|
+
# SageMath parsed files
|
|
156
|
+
*.sage.py
|
|
157
|
+
|
|
158
|
+
# Environments
|
|
159
|
+
.env
|
|
160
|
+
.envrc
|
|
161
|
+
.venv
|
|
162
|
+
env/
|
|
163
|
+
venv/
|
|
164
|
+
ENV/
|
|
165
|
+
env.bak/
|
|
166
|
+
venv.bak/
|
|
167
|
+
|
|
168
|
+
# Spyder project settings
|
|
169
|
+
.spyderproject
|
|
170
|
+
.spyproject
|
|
171
|
+
|
|
172
|
+
# Rope project settings
|
|
173
|
+
.ropeproject
|
|
174
|
+
|
|
175
|
+
# mkdocs documentation
|
|
176
|
+
/site
|
|
177
|
+
|
|
178
|
+
# mypy
|
|
179
|
+
.mypy_cache/
|
|
180
|
+
.dmypy.json
|
|
181
|
+
dmypy.json
|
|
182
|
+
|
|
183
|
+
# Pyre type checker
|
|
184
|
+
.pyre/
|
|
185
|
+
|
|
186
|
+
# pytype static type analyzer
|
|
187
|
+
.pytype/
|
|
188
|
+
|
|
189
|
+
# Cython debug symbols
|
|
190
|
+
cython_debug/
|
|
191
|
+
|
|
192
|
+
# PyCharm
|
|
193
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
194
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
195
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
196
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
197
|
+
# .idea/
|
|
198
|
+
|
|
199
|
+
# Abstra
|
|
200
|
+
# Abstra is an AI-powered process automation framework.
|
|
201
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
202
|
+
# Learn more at https://abstra.io/docs
|
|
203
|
+
.abstra/
|
|
204
|
+
|
|
205
|
+
# Visual Studio Code
|
|
206
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
207
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
208
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
209
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
210
|
+
# .vscode/
|
|
211
|
+
|
|
212
|
+
# Ruff stuff:
|
|
213
|
+
.ruff_cache/
|
|
214
|
+
|
|
215
|
+
# PyPI configuration file
|
|
216
|
+
.pypirc
|
|
217
|
+
|
|
218
|
+
# Marimo
|
|
219
|
+
marimo/_static/
|
|
220
|
+
marimo/_lsp/
|
|
221
|
+
__marimo__/
|
|
222
|
+
|
|
223
|
+
# Streamlit
|
|
224
|
+
.streamlit/secrets.toml
|
|
225
|
+
|
|
226
|
+
.DS_Store
|
|
227
|
+
.osgrep/
|
|
228
|
+
.osgrep
|
|
229
|
+
demo.db
|
|
230
|
+
demo.db-*
|
|
231
|
+
demos/areas_demo_async/outputs/
|
|
232
|
+
demos/areas_demo_async/cache/
|
|
233
|
+
demos/*.html
|
|
234
|
+
public-demos/_outputs_*/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-toml
|
|
9
|
+
- id: check-added-large-files
|
|
10
|
+
args: ["--maxkb=500"]
|
|
11
|
+
- id: debug-statements
|
|
12
|
+
|
|
13
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
14
|
+
rev: v0.11.6
|
|
15
|
+
hooks:
|
|
16
|
+
- id: ruff
|
|
17
|
+
args: [--fix]
|
|
18
|
+
- id: ruff-format
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"python.testing.pytestArgs": [
|
|
3
|
+
"tests"
|
|
4
|
+
],
|
|
5
|
+
"python.testing.unittestEnabled": false,
|
|
6
|
+
"python.testing.pytestEnabled": true,
|
|
7
|
+
"python-envs.pythonProjects": [
|
|
8
|
+
{
|
|
9
|
+
"path": ".",
|
|
10
|
+
"envManager": "ms-python.python:venv",
|
|
11
|
+
"packageManager": "ms-python.python:pip"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.4.0] - 2026-04-29
|
|
11
|
+
|
|
12
|
+
### Breaking
|
|
13
|
+
- `DEFAULT_BASE_URL` is now `https://api.infrared.city/v2` (was `https://api.infrared.city`). The previous default returned `403 {"message":"Forbidden"}` on every call because the AWS API Gateway custom domain `api.infrared.city` only has `/v2`, `/v1`, and `/v1.1` base-path mappings — there is no no-prefix mapping. Users who pinned the old default explicitly (constructor arg or `INFRARED_BASE_URL` env var) need to add `/v2`; users who relied on the default are unaffected (silently changes from "always 403" to "works"). The `/v2` mapping points at the production REST API; `/v1` and `/v1.1` continue to route to the older API for callers that explicitly opt in. (#98)
|
|
14
|
+
- `merge_area_jobs` (and therefore `run_area_and_wait`) now raises a new `AreaRunError` when every job in an area run terminates without producing a usable tile. Previously it returned an `AreaResult` with `succeeded_jobs=0` and an all-NaN merged grid — visually indistinguishable from a successful run unless the caller manually inspected `succeeded_jobs`. Callers that did not check `succeeded_jobs` will see exceptions in this scenario; wrap calls in `try ... except AreaRunError` to handle. Partial failures (≥1 success + ≥N failures) still return an `AreaResult` so callers don't lose the data they did get; jobs still pending also still return a result. The exception carries `failed_jobs`, `skipped_jobs`, `total_jobs`. The "no usable output" gate covers four paths: every job's server status was Failed; every download permanently errored; every grid was the wrong shape; every grid extractor raised. (#95)
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- `AreaRunError` exception — exported from the top-level package alongside `AreaTimeoutError` and `TiledRunError`. (#95)
|
|
18
|
+
- `AreaBuildings.failed_tiles: list[dict]` — partial-tile failures from `client.buildings.get_area(...)` are now surfaced on the returned object (each entry: `tile_id`, `row`, `col`, `error`). Empty list when every tile succeeded. The pre-existing log warning is unchanged. Same structural fix is recommended for `AreaVegetation` / `AreaGroundMaterials` next; tracked separately. (#95)
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- README weather example: replaced the obsolete `{"identifier": ..., "name": ...}` station-dict shape with the actual response (`uuid`, `fileName`, `location_data`) and updated the `filter_weather_data(identifier=locations[0]["uuid"], ...)` call accordingly. (#95)
|
|
22
|
+
- README quick-start examples for UTCI / TCS / PWC switched from a multi-month `TimePeriod` (which currently fails server-side with `DNI length 828 != sun_vectors 270`) to single-month windows that round-trip cleanly. Each affected snippet has a callout explaining the constraint. (#97)
|
|
23
|
+
- README Output Reference and AreaResult sections gained a `None`-fallback note for `min_legend` / `max_legend` — the API does not currently emit these for any analysis, so naive `zmin=result.min_legend` plotting passes `None` to matplotlib/Plotly. Snippets now use `np.nanmin/np.nanmax(merged_grid)` as the fallback. (#97)
|
|
24
|
+
- README `Error Handling` section now lists `AreaRunError`, `AreaTimeoutError`, and `TiledRunError` alongside the job-level error table; previously these area-level exceptions had no documented surface despite being raisable from the headline `run_area_and_wait` example. (#95)
|
|
25
|
+
- README "Install from source" block removed (referenced the private SDK source repo). `CONTRIBUTING.md` removed entirely (private repo, no external contributors). (#99, follow-ups)
|
|
26
|
+
|
|
27
|
+
### CI / dev infrastructure
|
|
28
|
+
- CI pipeline finally green: `ruff check`, `ruff format --check`, `pyright`, and `pytest --cov` all pass on Python 3.11/3.12/3.13. Previously every PR for ~3 days landed on a red pipeline (both v0.3.0 and v0.3.1 release merges shipped on red CI). Causes were structural lint debt (`E402` in `buildings/service.py`), 37 files drifted from the formatter, missing dev deps (`pytest-cov`), and the workflow calling `mypy` while the project configures `pyright`. (#102)
|
|
29
|
+
- `pytest-cov>=5.0` added to the `dev` dependency group.
|
|
30
|
+
- Workflow typecheck step switched from `mypy` to `pyright` to match the configured tool.
|
|
31
|
+
- Latent pyright errors fixed by widening 7 over-narrow signatures in `_area/_submission.py` and `tiling/tiles.py` (no behaviour change).
|
|
32
|
+
|
|
33
|
+
## [0.3.1] - 2026-04-29
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- `infrared_sdk.preflight.estimate_sun_context_loss(...)` — client-side pre-flight check that flags `direct-sun-hours` / daylight / solar / thermal-comfort configurations whose low-sun shadows exceed the per-tile geometry buffer. Returns a `SunContextResult` (`info` / `ok` / `marginal` / `warning` / `critical`) with a human-readable message. Pure math; no API calls; never raises (`#86`).
|
|
37
|
+
- `CLAUDE.md` — onboarding guide for AI assistants and human contributors covering repo layout, branching, conventions, and the PyPI release recipe.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- README: cookbook notebook URLs now point at `cookbook/notebooks/` in `Infrared-city/infrared-skills` (previously 404'd at the repo root) (#90).
|
|
41
|
+
- README: top-of-file link bar to https://infrared.city/docs/sdk/, the skills repo, and the knowledge base. Dropped CI badge that pointed at a non-existent repo (#92).
|
|
42
|
+
|
|
43
|
+
## [0.3.0] - 2026-04-28
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
- `TimePeriod` now validates calendar inputs: end-before-start, zero-length windows, and impossible day-of-month combinations (April 31, February 30, June 31, September 31, November 31) raise `ValidationError`. February 29 is accepted because `TimePeriod` carries no year context. Year-wrap windows (e.g. Nov→Feb) are not supported — split them into two periods.
|
|
47
|
+
- Typed exception hierarchy mirrored across service clients: `WeatherServiceError`, `BuildingsServiceError`, plus subclasses, and the `JobsServiceClient` hierarchy under `InfraredJobError` (#79). Response bodies live on `.response_body`, kept out of `args[0]` so they are not captured in default error-tracking message fields.
|
|
48
|
+
- HTTP timeouts on every outbound call across the 5 service clients (`(10, 300)` for control plane, `(10, 600)` for S3 downloads) (#79).
|
|
49
|
+
- `Retry-After` header is honored across the area orchestration path (submission, polling, result download) — when present on a 429/503, the SDK sleeps for the advertised duration instead of using jittered backoff. The header value is propagated through the typed exception hierarchy (`JobSubmitError.retry_after`, `JobPollError.retry_after`, `ResultsDownloadError.retry_after`) so the area path retries against the typed exceptions it actually catches. HTTP-date format is intentionally not parsed; only delta-seconds are honored.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- **Breaking**: `AreaState.from_job_states({})` now returns status `"empty"` instead of `"completed"`. Code that branches on `state.status == "completed"` for empty schedules will silently stop matching (#76). Migrate to either `state.is_complete` or `state.status in {"completed", "empty"}`.
|
|
53
|
+
- **Breaking**: error response bodies that previously could be reached via `exc.args[1]` now live exclusively on the typed `.response_body` attribute (#79).
|
|
54
|
+
- `AreaSchedule.jobs` is now a frozen `MappingProxyType` rather than a mutable dict. Direct mutation raises `TypeError`; rebuild a new schedule instead (#76).
|
|
55
|
+
- `TilingConfig.from_dict()` tolerates unknown keys, so newer configs from the server roll forward without breaking older clients (#78).
|
|
56
|
+
- `api_key` is wrapped in a `pydantic.SecretStr` to prevent plaintext leakage in logs and repr output (#72).
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
- Continent-scale polygons are pre-capped before tile materialization to avoid OOM (#75).
|
|
60
|
+
- Numpy polygon coordinates are canonicalized for dtype-stable tile IDs across float32/float64 inputs (#77).
|
|
61
|
+
- Zero-area polygons now raise `PolygonValidationError` instead of producing empty schedules silently (#74).
|
|
62
|
+
- `"nan"` strings in API responses are coerced to `None` rather than producing string fields where floats are expected (#74).
|
|
63
|
+
- `AreaResult.to_dict()` always emits `min_legend` and `max_legend` keys (set to `None` when no legend bounds are available) for stable downstream consumers (#73).
|
|
64
|
+
|
|
65
|
+
### Known limitations
|
|
66
|
+
- 100k-vertex polygons hit an O(n²) self-intersection check that can hang. Batch polygons through a simplifier first or split into smaller pieces. A sweep-line replacement is on the v0.3.x backlog.
|
|
67
|
+
|
|
68
|
+
## [0.2.0] - 2025-04-15
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
- Area orchestration API (`run_area`, `run_area_multi`, `run_area_and_wait`) for multi-tile polygon analysis
|
|
72
|
+
- Automatic polygon tiling with 512m tiles and 256m overlap blending
|
|
73
|
+
- `get_buildings_in_area()` for fetching, deduplicating, and transforming buildings across tiles
|
|
74
|
+
- Model-grouped tiling configuration for wind and solar analyses
|
|
75
|
+
- `gen_grid_image()` parameters: `analysis_type`, `criteria`, `subtype`
|
|
76
|
+
- Python 3.11 support with strict type checking
|
|
77
|
+
- Vegetation and ground materials pipeline (fetch, dedup, tile assignment)
|
|
78
|
+
- `x-infrared-application: sdk` header on all API requests
|
|
79
|
+
|
|
80
|
+
### Fixed
|
|
81
|
+
- Type errors for Python 3.11 strict type checking
|
|
82
|
+
- Single-line f-strings for Python 3.11 compatibility
|
|
83
|
+
|
|
84
|
+
## [0.1.0] - 2024-12-01
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
- Core analysis types: wind speed, pedestrian wind comfort, daylight availability, direct sun hours, sky view factors, solar radiation, thermal comfort index, thermal comfort statistics
|
|
88
|
+
- Async job system with exponential backoff polling
|
|
89
|
+
- Webhook integration for job status notifications
|
|
90
|
+
- Buildings API with DotBim, GeoJSON, and Mesh output formats
|
|
91
|
+
- Weather data API (search stations, fetch data, filter by time period)
|
|
92
|
+
- Grid image generation utility
|
|
93
|
+
- Context manager support for HTTP session lifecycle
|