Skip to content

New v1.0.0b8 Version - Enabling CRUD functionalities for STAC items #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 0 additions & 69 deletions .github/workflows/ci.yaml

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ on:
- main
- beta/*
pull_request:
branches:
- main
- beta/*
workflow_dispatch:
schedule:
- cron: '31 17 * * 5'

jobs:
analyze:
if: ${{ !github.event.repository.private }} # Only run on public repos

name: Analyze (${{ matrix.language }})
runs-on: 'ubuntu-latest'
permissions:
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Lint, Format and Type Check

on:
push:
branches:
- main
- beta/*
pull_request:
workflow_dispatch:

jobs:
lint:
runs-on: ${{ github.repository_visibility == 'private' && 'ed-runner-set' || 'ubuntu-latest' }}
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
container:
image: python:${{ matrix.python-version }}

steps:
- uses: actions/checkout@v4

- name: Install system dependencies
run: |
apt-get update
apt-get install -y gdal-bin libgdal-dev

- name: Install Poetry
run: pip install poetry

- name: Install test dependencies
run: poetry install --only tests

- name: Run Linting
run: poetry run tox -e lint

- name: Run Formatting Check
run: poetry run tox -e format
6 changes: 5 additions & 1 deletion .github/workflows/publish_pypi_on_tag.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ on:

jobs:
pypi-publish:
if: ${{ !github.event.repository.private }} # Only run on public repos

name: Upload release to PyPI
runs-on: ubuntu-latest
container:
image: ubuntu:latest
environment:
name: pypi
url: https://pypi.org/p/earthdaily
Expand All @@ -19,7 +23,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
python-version: "3.13"

- name: Install Poetry
run: pip install poetry
Expand Down
52 changes: 52 additions & 0 deletions .github/workflows/publish_to_codeartifact.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Publish to CodeArtifact

on:
push:
branches:
- main

jobs:
publish-to-codeartifact:
name: Upload to AWS CodeArtifact
runs-on: [ed-runner-set]
container:
image: python:3.13-slim

steps:
- name: Install system dependencies
run: |
apt-get update
apt-get install -y curl unzip gnupg awscli build-essential

- name: Checkout repo
uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1

- name: Install Poetry
run: pip install poetry

- name: Clean old dist
run: rm -rf dist/

- name: Build package with Poetry
run: poetry build

- name: Login to CodeArtifact
run: |
aws codeartifact login \
--tool twine \
--repository pypi \
--domain urthecast \
--domain-owner ${{ secrets.FGPROD_ACCOUNT_ID }} \
--region us-east-1

- name: Install twine and publish to CodeArtifact
run: |
pip install twine
twine upload --repository codeartifact dist/* --verbose
Comment on lines +10 to +52

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 3 days ago

To fix the issue, we will add a permissions block to the workflow. Since the workflow primarily interacts with the repository contents and does not require write access to other resources, we will set contents: read at the workflow level. This ensures that the GITHUB_TOKEN has minimal permissions, adhering to the principle of least privilege.

The permissions block will be added at the root level of the workflow, just below the name field, so it applies to all jobs in the workflow.


Suggested changeset 1
.github/workflows/publish_to_codeartifact.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/publish_to_codeartifact.yaml b/.github/workflows/publish_to_codeartifact.yaml
--- a/.github/workflows/publish_to_codeartifact.yaml
+++ b/.github/workflows/publish_to_codeartifact.yaml
@@ -1,2 +1,4 @@
 name: Publish to CodeArtifact
+permissions:
+  contents: read
 
EOF
@@ -1,2 +1,4 @@
name: Publish to CodeArtifact
permissions:
contents: read

Copilot is powered by AI and may make mistakes. Always verify output.
35 changes: 21 additions & 14 deletions .github/workflows/secret-scanning.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
name: "Secret Scanning"
name: Secret Scanning

on:
push:
branches:
- main
- beta/*
pull_request:
branches:
- main
- beta/*
workflow_dispatch:

jobs:
secret-scan:
name: Scan for Secrets
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
security-secrets:
name: TruffleHog Secret Scan
runs-on: ${{ github.repository_visibility == 'private' && 'ed-runner-set' || 'ubuntu-latest' }}
container:
image: alpine:latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Git and dependencies
run: |
apk add --no-cache git curl jq

- name: Clone the repository manually
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git clone https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git repo
cd repo

# install TruffleHog
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh | sh -s -- -b /usr/local/bin

- name: Run TruffleHog OSS
uses: trufflesecurity/trufflehog@v3.88.17
# run TruffleHog scan
trufflehog filesystem "." --results=verified,unknown --fail --json | jq
Comment on lines +13 to +33

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 7 days ago

To fix the issue, we will add a permissions block at the workflow level to explicitly define the minimal permissions required. Since the workflow only needs to read the repository contents to perform the secret scan, we will set contents: read. This ensures that the GITHUB_TOKEN has the least privileges necessary to complete the task.

Suggested changeset 1
.github/workflows/secret-scanning.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/secret-scanning.yml b/.github/workflows/secret-scanning.yml
--- a/.github/workflows/secret-scanning.yml
+++ b/.github/workflows/secret-scanning.yml
@@ -10,2 +10,5 @@
 
+permissions:
+  contents: read
+
 jobs:
EOF
@@ -10,2 +10,5 @@

permissions:
contents: read

jobs:
Copilot is powered by AI and may make mistakes. Always verify output.
45 changes: 45 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: earthdaily-python-client CI

on:
push:
branches:
- main
- beta/*
pull_request:
workflow_dispatch:

jobs:
test:
name: Unit Tests (Python ${{ matrix.python-version }})
runs-on: ${{ github.repository_visibility == 'private' && 'ed-runner-set' || 'ubuntu-latest' }}
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
include:
- python-version: "3.10"
tox_env: py310
- python-version: "3.11"
tox_env: py311
- python-version: "3.12"
tox_env: py312
- python-version: "3.13"
tox_env: py313
container:
image: python:${{ matrix.python-version }}

steps:
- uses: actions/checkout@v4

- name: Install GDAL and dependencies
run: |
apt-get update
apt-get install -y gdal-bin libgdal-dev

- name: Install Poetry
run: pip install poetry

- name: Install test dependencies
run: poetry install --only tests

- name: Run tests with tox
run: poetry run tox -e ${{ matrix.tox_env }}
Comment on lines +13 to +45

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 7 days ago

To fix the issue, we will add a permissions block at the workflow level (root) to restrict the GITHUB_TOKEN permissions to contents: read. This is sufficient for the current workflow, as it only needs to read repository contents to run tests. This change will ensure that the workflow adheres to the principle of least privilege.


Suggested changeset 1
.github/workflows/test.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -1,2 +1,4 @@
 name: earthdaily-python-client CI
+permissions:
+  contents: read
 
EOF
@@ -1,2 +1,4 @@
name: earthdaily-python-client CI
permissions:
contents: read

Copilot is powered by AI and may make mistakes. Always verify output.
27 changes: 27 additions & 0 deletions earthdaily/_eds_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
from earthdaily.legacy import EarthDataStore
from earthdaily.platform import PlatformService

try:
from earthdaily.internal import InternalService

_HAS_INTERNAL = True
except ImportError:
_HAS_INTERNAL = False


class EDSClient:
"""
Expand Down Expand Up @@ -78,3 +85,23 @@ def legacy(self):
if not hasattr(self, "_legacy_service"):
self._legacy_service = EarthDataStore(self.api_requester)
return self._legacy_service

@property
def internal(self):
"""
Lazily initializes and returns the InternalService for interacting with internal API endpoints.

Returns:
-------
InternalService:
The service that interacts with internal API operations.
Raises:
-------
NotImplementedError:
If the internal module is not available in this build of EDSClient.
"""
if not _HAS_INTERNAL:
raise NotImplementedError("The 'internal' module is not available in this build of EDSClient.")
if not hasattr(self, "_internal_service"):
self._internal_service = InternalService(self.api_requester)
return self._internal_service
8 changes: 7 additions & 1 deletion earthdaily/_http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,14 @@ def send(self, request: HTTPRequest) -> HTTPResponse:
timeout=request.timeout_seconds,
)

# Handle responses with no content (204) or empty bodies
try:
body = response.json() if response.content else {}
except (ValueError, requests.exceptions.JSONDecodeError):
body = {}

return HTTPResponse(
status_code=response.status_code,
body=response.json(),
body=body,
headers=response.headers,
)
8 changes: 8 additions & 0 deletions earthdaily/platform/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
from pystac_client.stac_api_io import StacApiIO

from earthdaily._api_requester import APIRequester
from earthdaily.platform._bulk_delete import BulkDeleteService
from earthdaily.platform._bulk_insert import BulkInsertService
from earthdaily.platform._bulk_search import BulkSearchService
from earthdaily.platform._stac_item import StacItemService


class PlatformService:
Expand All @@ -26,6 +30,10 @@ def __init__(self, api_requester: APIRequester, pre_sign_urls: bool):
A flag indicating whether to use pre-signed URLs for asset access.
"""
self.api_requester = api_requester
self.bulk_search = BulkSearchService(api_requester)
self.bulk_insert = BulkInsertService(api_requester)
self.bulk_delete = BulkDeleteService(api_requester)
self.stac_item = StacItemService(api_requester)

self.pystac_client = Client.open(
f"{api_requester.base_url}/platform/v1/stac",
Expand Down
Loading