{"id":13735510,"url":"https://github.com/geospatial-jeff/aiocogeo","last_synced_at":"2026-03-05T05:31:59.258Z","repository":{"id":49119485,"uuid":"250858544","full_name":"geospatial-jeff/aiocogeo","owner":"geospatial-jeff","description":"Asynchronous cogeotiff reader","archived":false,"fork":false,"pushed_at":"2021-07-02T07:24:45.000Z","size":234,"stargazers_count":76,"open_issues_count":29,"forks_count":10,"subscribers_count":10,"default_branch":"master","last_synced_at":"2026-01-24T05:52:04.325Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/geospatial-jeff.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.txt","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-28T17:50:12.000Z","updated_at":"2025-05-15T18:22:30.000Z","dependencies_parsed_at":"2022-09-05T13:12:08.858Z","dependency_job_id":null,"html_url":"https://github.com/geospatial-jeff/aiocogeo","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/geospatial-jeff/aiocogeo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geospatial-jeff%2Faiocogeo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geospatial-jeff%2Faiocogeo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geospatial-jeff%2Faiocogeo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geospatial-jeff%2Faiocogeo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geospatial-jeff","download_url":"https://codeload.github.com/geospatial-jeff/aiocogeo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geospatial-jeff%2Faiocogeo/sbom","scorecard":{"id":423394,"data":{"date":"2025-08-11","repo":{"name":"github.com/geospatial-jeff/aiocogeo","commit":"5a1d32c3f22c883354804168a87abb0a2ea1c328"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":1,"reason":"Found 3/30 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/geospatial-jeff/aiocogeo/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/geospatial-jeff/aiocogeo/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/geospatial-jeff/aiocogeo/ci.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:30","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T01:45:31.470Z","repository_id":49119485,"created_at":"2025-08-19T01:45:31.470Z","updated_at":"2025-08-19T01:45:31.470Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30111743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T03:40:26.266Z","status":"ssl_error","status_checked_at":"2026-03-05T03:39:15.902Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":"2024-08-03T03:01:07.640Z","updated_at":"2026-03-05T05:31:59.218Z","avatar_url":"https://github.com/geospatial-jeff.png","language":"Python","funding_links":[],"categories":["`Python` processing of optical imagery (non deep learning)","Python"],"sub_categories":["Cloud Native Geospatial"],"readme":"# aiocogeo\n[![GHA](https://github.com/geospatial-jeff/aiocogeo/workflows/CI/badge.svg)](https://github.com/geospatial-jeff/aiocogeo/actions?query=workflow%3ACI)\n[![codecov](https://codecov.io/gh/geospatial-jeff/aiocogeo/branch/master/graph/badge.svg)](https://codecov.io/gh/geospatial-jeff/aiocogeo)\n[![pypi](https://img.shields.io/pypi/v/aiocogeo?color=%2334D058\u0026label=pypi%20package)](https://pypi.org/project/aiocogeo)\n[![license](https://img.shields.io/github/license/geospatial-jeff/aiocogeo.svg)](https://github.com/geospatial-jeff/aiocogeo/blob/master/LICENSE)\n\n## Installation\n```\npip install aiocogeo\n\n# With S3 filesystem\npip install aiocogeo[s3]\n```\n\n## Usage\nCOGs are opened using the `COGReader` asynchronous context manager:\n\n```python\nfrom aiocogeo import COGReader\n\nasync with COGReader(\"http://cog.tif\") as cog:\n    ...\n```\n\nSeveral filesystems are supported:\n- **HTTP/HTTPS** (`http://`, `https://`)\n- **S3** (`s3://`)\n- **File** (`/`)\n\n### Metadata\nGenerating a [rasterio-style profile](https://rasterio.readthedocs.io/en/latest/topics/profiles.html) for the COG:\n\n```python\nasync with COGReader(\"https://async-cog-reader-test-data.s3.amazonaws.com/lzw_cog.tif\") as cog:\n    print(cog.profile)\n\n\u003e\u003e\u003e {'driver': 'GTiff', 'width': 10280, 'height': 12190, 'count': 3, 'dtype': 'uint8', 'transform': Affine(0.6, 0.0, 367188.0,\n       0.0, -0.6, 3777102.0), 'blockxsize': 512, 'blockysize': 512, 'compress': 'lzw', 'interleave': 'pixel', 'crs': 'EPSG:26911', 'tiled': True, 'photometric': 'rgb'}\n```\n\n#### Lower Level Metadata\nA COG is composed of several IFDs, each with many TIFF tags:\n\n```python\nfrom aiocogeo.ifd import IFD\nfrom aiocogeo.tag import Tag\n\nasync with COGReader(\"https://async-cog-reader-test-data.s3.amazonaws.com/lzw_cog.tif\") as cog:\n    for ifd in cog:\n        assert isinstance(ifd, IFD)\n        for tag in ifd:\n            assert isinstance(tag, Tag)\n```\n\nEach IFD contains more granular metadata about the image than what is included in the profile.  For example, finding the\ntilesize for each IFD:\n\n```python\nasync with COGReader(\"https://async-cog-reader-test-data.s3.amazonaws.com/lzw_cog.tif\") as cog:\n    for ifd in cog:\n        print(ifd.TileWidth.value, ifd.TileHeight.value)\n\n\u003e\u003e\u003e 512 512\n    128 128\n    128 128\n    128 128\n    128 128\n    128 128\n```\n\nMore advanced use cases may need access to tag-level metadata:\n```python\nasync with COGReader(\"https://async-cog-reader-test-data.s3.amazonaws.com/lzw_cog.tif\") as cog:\n    first_ifd = cog.ifds[0]\n    assert first_ifd.tag_count == 24\n\n    for tag in first_ifd:\n        print(tag)\n\n\u003e\u003e\u003e Tag(code=258, name='BitsPerSample', tag_type=TagType(format='H', size=2), count=3, length=6, value=(8, 8, 8))\n    Tag(code=259, name='Compression', tag_type=TagType(format='H', size=2), count=1, length=2, value=5)\n    Tag(code=257, name='ImageHeight', tag_type=TagType(format='H', size=2), count=1, length=2, value=12190)\n    Tag(code=256, name='ImageWidth', tag_type=TagType(format='H', size=2), count=1, length=2, value=10280)\n    ...\n```\n\n### Image Data\nThe reader also has methods for reading internal image tiles and performing partial reads.  Currently only jpeg, lzw, deflate, packbits, and webp compressions are supported.\n\n#### Image Tiles\nReading the top left tile of an image at native resolution:\n\n```python\nasync with COGReader(\"https://async-cog-reader-test-data.s3.amazonaws.com/webp_cog.tif\") as cog:\n    x = y = z = 0\n    tile = await cog.get_tile(x, y, z)\n\n    ifd = cog.ifds[z]\n    assert tile.shape == (ifd.bands, ifd.TileHeight.value, ifd.TileWidth.value)\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"300\" height=\"300\" src=\"https://async-cog-reader-test-data.s3.amazonaws.com/readme/naip_top_left_tile.jpg\"\u003e\n\u003c/p\u003e\n\n\n#### Partial Read\nYou can read a portion of the image by specifying a bounding box in the native crs of the image and an output shape:\n\n```python\nasync with COGReader(\"https://async-cog-reader-test-data.s3.amazonaws.com/webp_cog.tif\") as cog:\n    assert cog.epsg == 26911\n    partial_data = await cog.read(bounds=(368461,3770591,368796,3770921), shape=(512,512))\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"300\" height=\"300\" src=\"https://async-cog-reader-test-data.s3.amazonaws.com/readme/partial_read.jpeg\"\u003e\n\u003c/p\u003e\n\n#### Internal Masks\nIf the COG has an internal mask, the returned array will be a masked array:\n\n```python\nimport numpy as np\n\nasync with COGReader(\"https://async-cog-reader-test-data.s3.amazonaws.com/naip_image_masked.tif\") as cog:\n    assert cog.is_masked\n\n    tile = await cog.get_tile(0,0,0)\n    assert np.ma.is_masked(tile)\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://async-cog-reader-test-data.s3.amazonaws.com/readme/masked_tile.jpg\" width=\"300\" /\u003e\n  \u003cimg src=\"https://async-cog-reader-test-data.s3.amazonaws.com/readme/mask.jpg\" width=\"300\" /\u003e\n\u003c/p\u003e\n\n### Configuration\nConfiguration options are exposed through environment variables:\n- **INGESTED_BYTES_AT_OPEN** - defines the number of bytes in the first GET request at file opening (defaults to 16KB)\n- **HEADER_CHUNK_SIZE** - chunk size used to read header (defaults to 16KB)\n- **ENABLE_BLOCK_CACHE** - determines if image blocks are cached in memory (defaults to TRUE)\n- **ENABLE_HEADER_CACHE** - determines if COG headers are cached in memory (defaults to TRUE)\n- **HTTP_MERGE_CONSECUTIVE_RANGES** - determines if consecutive ranges are merged into a single request (defaults to FALSE)\n- **BOUNDLESS_READ** - determines if internal tiles outside the bounds of the IFD are read (defaults to TRUE)\n- **BOUNDLESS_READ_FILL_VALUE** - determines the value used to fill boundless reads (defaults to 0)\n- **LOG_LEVEL** - determines the log level used by the package (defaults to ERROR)\n- **VERBOSE_LOGS** - enables verbose logging, designed for use when `LOG_LEVEL=DEBUG` (defaults to FALSE)\n- **AWS_REQUEST_PAYER** - set to `requester` to enable reading from S3 RequesterPays buckets.\n- **ZOOM_LEVEL_STRATEGY** - mimics [GDAL's `ZOOM_LEVEL_STRATEGY` creation option](https://gdal.org/drivers/raster/cog.html#reprojection-related-creation-options):\n  - `AUTO` or `50` (default) upsamples or downsamples the zoom level whose resolution is closest to the desired resolution.\n  - `LOWER` or `100` always upsamples the zoom level immediately below the desired resolution (requesting less data).\n  - `UPPER` or `0` always downsamples the zoom level immediately above the desired resoluion (requesting more data).\n  - Another integer from `0` through `100`: if the desired resolution more this _percentage_ of the way from the zoom level immediately below to the zoom level immediately above, then upsample the zoom level immediately below, else downsample the zoom level immediately above. For example, `1` is the same as `UPPER` unless the COG's resolution is very close to the zoom level below e.g. due to floating point imprecision.\n\nRefer to [`aiocogeo/config.py`](https://github.com/geospatial-jeff/aiocogeo/blob/master/aiocogeo/config.py) for more details about configuration options.\n\n## CLI\n```\n$ aiocogeo --help\nUsage: aiocogeo [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --install-completion [bash|zsh|fish|powershell|pwsh]\n                                  Install completion for the specified shell.\n  --show-completion [bash|zsh|fish|powershell|pwsh]\n                                  Show completion for the specified shell, to\n                                  copy it or customize the installation.\n\n  --help                          Show this message and exit.\n\nCommands:\n  create-tms  Create OGC TileMatrixSet.\n  info        Read COG metadata.\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeospatial-jeff%2Faiocogeo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeospatial-jeff%2Faiocogeo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeospatial-jeff%2Faiocogeo/lists"}