Skip to content
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

Add files #33

Merged
merged 4 commits into from
Mar 25, 2024
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
112 changes: 98 additions & 14 deletions openeo_fastapi/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ def register_get_conformance(self):
endpoint=self.client.get_conformance,
)

def register_get_file_formats(self):
"""Register conformance page (GET /file_formats).
Returns:
None
"""
self.router.add_api_route(
name="conformance",
path=f"/{self.client.settings.OPENEO_VERSION}/file_formats",
response_model=responses.FileFormatsGetResponse,
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client.get_file_formats,
)

def register_get_collections(self):
"""Register collection Endpoint (GET /collections).
Returns:
Expand All @@ -76,7 +91,7 @@ def register_get_collections(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._collections.get_collections,
endpoint=self.client.collections.get_collections,
)

def register_get_collection(self):
Expand All @@ -92,7 +107,7 @@ def register_get_collection(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._collections.get_collection,
endpoint=self.client.collections.get_collection,
)

def register_get_processes(self):
Expand All @@ -108,7 +123,7 @@ def register_get_processes(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._processes.list_processes,
endpoint=self.client.processes.list_processes,
)

def register_get_jobs(self):
Expand All @@ -124,7 +139,7 @@ def register_get_jobs(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._jobs.list_jobs,
endpoint=self.client.jobs.list_jobs,
)

def register_create_job(self):
Expand All @@ -140,7 +155,7 @@ def register_create_job(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["POST"],
endpoint=self.client._jobs.create_job,
endpoint=self.client.jobs.create_job,
)

def register_update_job(self):
Expand All @@ -156,7 +171,7 @@ def register_update_job(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["PATCH"],
endpoint=self.client._jobs.update_job,
endpoint=self.client.jobs.update_job,
)

def register_get_job(self):
Expand All @@ -172,7 +187,7 @@ def register_get_job(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._jobs.get_job,
endpoint=self.client.jobs.get_job,
)

def register_delete_job(self):
Expand All @@ -188,7 +203,7 @@ def register_delete_job(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["DELETE"],
endpoint=self.client._jobs.delete_job,
endpoint=self.client.jobs.delete_job,
)

def register_get_estimate(self):
Expand All @@ -204,7 +219,7 @@ def register_get_estimate(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._jobs.estimate,
endpoint=self.client.jobs.estimate,
)

def register_get_logs(self):
Expand All @@ -220,7 +235,7 @@ def register_get_logs(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._jobs.logs,
endpoint=self.client.jobs.logs,
)

def register_get_results(self):
Expand All @@ -236,7 +251,7 @@ def register_get_results(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client._jobs.get_results,
endpoint=self.client.jobs.get_results,
)

def register_start_job(self):
Expand All @@ -252,7 +267,7 @@ def register_start_job(self):
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["POST"],
endpoint=self.client._jobs.start_job,
endpoint=self.client.jobs.start_job,
)

def register_cancel_job(self):
Expand All @@ -262,13 +277,77 @@ def register_cancel_job(self):
None
"""
self.router.add_api_route(
name="start_job",
name="cancel_job",
path=f"/{self.client.settings.OPENEO_VERSION}/jobs" + "/{job_id}/results",
response_model=None,
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["DELETE"],
endpoint=self.client._jobs.cancel_job,
endpoint=self.client.jobs.cancel_job,
)

def register_list_files(self):
"""Register Endpoint for Files (GET /files).

Returns:
None
"""
self.router.add_api_route(
name="list_files",
path=f"/{self.client.settings.OPENEO_VERSION}/files",
response_model=None,
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client.files.list_files,
)

def register_download_file(self):
"""Register Endpoint for Files (GET /files/{path}).

Returns:
None
"""
self.router.add_api_route(
name="download_file",
path=f"/{self.client.settings.OPENEO_VERSION}/files" + "/{path}",
response_model=None,
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["GET"],
endpoint=self.client.files.download_file,
)

def register_upload_file(self):
"""Register Endpoint for Files (PUT /files/{path}).

Returns:
None
"""
self.router.add_api_route(
name="upload_file",
path=f"/{self.client.settings.OPENEO_VERSION}/files" + "/{path}",
response_model=None,
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["PUT"],
endpoint=self.client.files.upload_file,
)

def register_delete_file(self):
"""Register Endpoint for Files (DELETE /files/{path}).

Returns:
None
"""
self.router.add_api_route(
name="delete_file",
path=f"/{self.client.settings.OPENEO_VERSION}/files" + "/{path}",
response_model=None,
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["DELETE"],
endpoint=self.client.files.delete_file,
)

def register_core(self):
Expand All @@ -288,6 +367,7 @@ def register_core(self):
None
"""
self.register_get_conformance()
self.register_get_file_formats()
self.register_get_collections()
self.register_get_collection()
self.register_get_processes()
Expand All @@ -301,6 +381,10 @@ def register_core(self):
self.register_get_results()
self.register_start_job()
self.register_cancel_job()
self.register_list_files()
self.register_download_file()
self.register_upload_file()
self.register_delete_file()
self.register_well_known()

def http_exception_handler(self, request, exception):
Expand Down
22 changes: 21 additions & 1 deletion openeo_fastapi/api/responses.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import uuid
from enum import Enum
from typing import Any, Optional, TypedDict, Union
from typing import Any, Dict, List, Optional, TypedDict, Union

from pydantic import AnyUrl, BaseModel, Extra, Field, validator

from openeo_fastapi.api.types import (
Billing,
Endpoint,
File,
FileFormat,
Link,
Process,
RFC3339Datetime,
Expand Down Expand Up @@ -451,3 +453,21 @@ class JobsGetEstimateGetResponse(BaseModel):
description="Time until which the estimate is valid, formatted as a [RFC 3339](https://www.rfc-editor.org/rfc/RFC3339Datetime.html) date-time.",
example="2020-11-01T00:00:00Z",
)


class FilesGetResponse(BaseModel):
files: list[File]
links: list[Link]


class FileFormatsGetResponse(BaseModel):
input: dict[str, FileFormat] = Field(
...,
description="Map of supported input file formats, i.e. file formats a back-end can **read** from. The property keys are the file format names that are used by clients and users, for example in process graphs.",
title="Input File Formats",
)
output: dict[str, FileFormat] = Field(
...,
description="Map of supported output file formats, i.e. file formats a back-end can **write** to. The property keys are the file format names that are used by clients and users, for example in process graphs.",
title="Output File Formats",
)
43 changes: 42 additions & 1 deletion openeo_fastapi/api/types.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
from enum import Enum
from pathlib import Path
from typing import Any, List, Optional, Union
from typing import Any, Dict, List, Optional, Union

from pydantic import AnyUrl, BaseModel, Extra, Field, validator

Expand Down Expand Up @@ -57,6 +57,13 @@ class Level(Enum):
debug = "debug"


class GisDataType(Enum):
raster = "raster"
vector = "vector"
table = "table"
other = "other"


class RFC3339Datetime(BaseModel):
"""Class to consistently represent datetimes as strings compliant to RFC3339Datetime."""

Expand Down Expand Up @@ -180,6 +187,20 @@ class Billing(BaseModel):
)


class File(BaseModel):
path: str = Field(
...,
description="Path of the file, relative to the root directory of the user's server-side workspace.\nMUST NOT start with a slash `/` and MUST NOT be url-encoded.\n\nThe Windows-style path name component separator `\\` is not supported,\nalways use `/` instead.\n\nNote: The pattern only specifies a minimal subset of invalid characters.\nThe back-ends MAY enforce additional restrictions depending on their OS/environment.",
example="folder/file.txt",
)
size: Optional[int] = Field(None, description="File size in bytes.", example=1024)
modified: Optional[RFC3339Datetime] = Field(
None,
description="Date and time the file has lastly been modified, formatted as a [RFC 3339](https://www.rfc-editor.org/rfc/RFC3339Datetime.html) date-time.",
example="2018-01-03T10:55:29Z",
)


class UsageMetric(BaseModel):
value: float
unit: str
Expand Down Expand Up @@ -303,3 +324,23 @@ class Error(BaseModel):
example="Parameter 'sample' is missing.",
)
links: Optional[list[Link]] = None


class FileFormat(BaseModel):
title: str
description: Optional[str] = None
gis_data_types: list[GisDataType] = Field(
...,
description="Specifies the supported GIS spatial data types for this format.\nIt is RECOMMENDED to specify at least one of the data types, which will likely become a requirement in a future API version.",
)
deprecated: Optional[bool] = None
experimental: Optional[bool] = None
parameters: dict[str, Any] = Field(
...,
description="Specifies the supported parameters for this file format.",
title="File Format Parameters",
)
links: Optional[list[Link]] = Field(
None,
description="Links related to this file format, e.g. external documentation.\n\nFor relation types see the lists of\n[common relation types in openEO](#section/API-Principles/Web-Linking).",
)
22 changes: 12 additions & 10 deletions openeo_fastapi/client/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
from openeo_fastapi.api.types import Endpoint, Error
from openeo_fastapi.client.register import EndpointRegister

COLLECTIONS_ENDPOINTS = [
Endpoint(
path="/collections",
methods=["GET"],
),
Endpoint(
path="/collections/{collection_id}",
methods=["GET"],
),
]


class CollectionRegister(EndpointRegister):
def __init__(self, settings) -> None:
Expand All @@ -13,16 +24,7 @@ def __init__(self, settings) -> None:
self.settings = settings

def _initialize_endpoints(self) -> list[Endpoint]:
return [
Endpoint(
path="/collections",
methods=["GET"],
),
Endpoint(
path="/collections/{collection_id}",
methods=["GET"],
),
]
return COLLECTIONS_ENDPOINTS

async def _proxy_request(self, path):
"""
Expand Down
Loading
Loading