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

Doc ci #43

Merged
merged 2 commits into from
Apr 8, 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
3 changes: 3 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ jobs:

- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

- name: Build new documentation
run: mkdocs gh-deploy
Empty file removed docs/guide/adding.md
Empty file.
1 change: 1 addition & 0 deletions docs/guide/auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## To be defined
Empty file removed docs/guide/overriding.md
Empty file.
108 changes: 108 additions & 0 deletions docs/guide/registers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
## Editing the registers.

The endpoint registers are a loose abstraction defining what endpoints a register is responsible for, and also what code is expected to be executed for those endpoints.

The available registers can be imported as follows.

from openeo_fastapi.client.jobs import JobsRegister
from openeo_fastapi.client.files import FilesRegister
from openeo_fastapi.client.processes import ProcessesRegister
from openeo_fastapi.client.collections import CollectionsRegister

You will need to know how you are expected to overwrite the functionality of these registers, as the openeo-fastapi package does not define functionality for all available endpoints.

## How to overwrite an endpoint.

In the following example, we import the FileRegister, and overwrite the functionality for the list_files method. This will define a new response for that endpoint. This is the framework for editing the functionality of the api endpoints.

from openeo_fastapi.client.files import FilesRegister

class OverwrittenFileRegister(FilesRegister):
def __init__(self, settings, links) -> None:
super().__init__(settings, links)

def list_files(
self,
limit: Optional[int] = 10
):
""" """
return FilesGetResponse(
files=[File(path="/somefile.txt", size=10)],
links=[
Link(
href="https://eodc.eu/",
rel="about",
type="text/html",
title="Homepage of the service provider",
)
],
)

In order to use this overwritten file register, we instantiate the register, and parse this to the OpenEOCore object. Now, when the api is next deployed, we will return the FilesGetResponse, and not the default HTTPException.

extended_register = OverwrittenFileRegister(app_settings, test_links)

client = OpenEOCore(
...
files=extended_register,
...
)

api = OpenEOApi(client=client, app=FastAPI())

## How to add an endpoint

The registers can also be extended to include extra functionality. In order to do this, we again need to define a new child class for the register you want to extend.

We can define a new endpoint for the api as follows.

from openeo_fastapi.api.types import Endpoint
new_endpoint = Endpoint(
path="/files/{path}",
methods=["HEAD"],
)

When defining the child register, the *_initialize_endpoints* method needs to be redefined to add the new_endpoint object. The new functionality can be defined under a new function, here *get_file_headers*.

from openeo_fastapi.client.files import FilesRegister, FILE_ENDPOINTS

class ExtendedFileRegister(FilesRegister):
def __init__(self, settings, links) -> None:
super().__init__(settings, links)
self.endpoints = self._initialize_endpoints()

def _initialize_endpoints(self) -> list[Endpoint]:
endpoints = list(FILE_ENDPOINTS)
endpoints.append(new_endpoint)
return endpoints

def get_file_headers(
self, path: str, user: User = Depends(Authenticator.validate)
):
""" """
return Response(
status_code=200,
headers={
"Accept-Ranges": "bytes",
},
)

client = OpenEOCore(
...
files=extended_register,
...
)

api = OpenEOApi(client=client, app=FastAPI())

So far, we have made the new code available to the api, but the api does not know how or when to execute the new code. The following snippet will register the new path to the api server, along with the functionality.

api.app.router.add_api_route(
name="file_headers",
path=f"/{api.client.settings.OPENEO_VERSION}/files" + "/{path}",
response_model=None,
response_model_exclude_unset=False,
response_model_exclude_none=True,
methods=["HEAD"],
endpoint=api.client.files.get_file_headers,
)
1 change: 0 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ to the database schema, and finally increase the offering of the baseline api wi
would like to add.

* [Getting Started](setup.md)
* [User Guide](setup.md)
96 changes: 95 additions & 1 deletion docs/setup.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,99 @@
# Getting Started

Everything on this page is all you need to go from 0 to having your OpenEO Api server running locally.

## Environment Setup

The openeo-fastapi package comes with a couple of assumptions. The first assumption, is the package is used to build a server side application. The second assumption is that the user is able to provide a connection to a psql database. The final assumption, is the user has provided the set of required environment variables which are needed for the application to run.

The following steps will explain how the user can get the application skeleton to run.

## Installation

pip install openeo-fastapi
Prior to installation, configure and activate a virtual environment for your new project, I can recommend using [poetry](https://python-poetry.org/docs/basic-usage/) for this. Once the environment is activate continue with installing openeo-fastapi.


pip install openeo-fastapi

## Command line interface

The openeo-fastapi CLI can be used to set up a quick source directory for your deployment.

openeo_fastapi new /path/to/source/directory

The command line interface will create the following directory tree.

src/
__init__.py
app.py
revise.py
/psql
alembic.ini
models.py
alembic/
env.py
README
script.py.mako
versions/


The **app.py** file defines the minimal code to define the FastApi application to deploy the API.

The **revise.py** file defines steps that can be used to generate and apply
alembic revisions to the database deployment. This file is intended to be used after a new release of your deployment, but before your release has been deployed, i.e. as part of an initialization container. This file is optional and can be deleted if you want to complete these steps in a different way.

The **/psql** directory is used for housing the alembic directory to record the alembic revision history and connectivity to the database. All files ( apart from models.py ) are generated from the alembic init command, so refer to the [alembic docs](https://alembic.sqlalchemy.org/en/latest/) for more information on those files.

The **/psql/models.py** file defines the basis for importing the orm models from the OpenEO FastApi and defining the metadata class that can then be imported and used in the alembic *env.py* file.

The **/psql/alembic/env.py** file needs a couple of edits.

Set the main option for the psql connection.

config.set_main_option(
"sqlalchemy.url",
f"postgresql://{environ.get('POSTGRES_USER')}:{environ.get('POSTGRES_PASSWORD')}"
f"@{environ.get('POSTGRESQL_HOST')}:{environ.get('POSTGRESQL_PORT')}"
f"/{environ.get('POSTGRES_DB')}",
)

Set the target metadata. In this example, I am importing from the **/psql/models.py** file.

from openeo_api.psql.models import metadata
target_metadata = metadata


## Set the environment variables

These variables need to be set in the environment of the deployment. Those marked required need to be set, and those set False, have some default value that only needs to be provided

| Variable | Description | Required |
| -------- | ------- | ------- |
| API_DNS | The domain name hosting the API. | True |
| API_TLS | Whether the API http scheme should be http or https. | True |
| API_TITLE | The API title to be provided to FastAPI. | True |
| API_DESCRIPTION | The API description to be provided to FastAPI. | True |
| OPENEO_VERSION | The OpenEO Api specification version supported in this deployment of the API. Defaults to "1.1.0". | False |
| OPENEO_PREFIX | The OpenEO prefix to be used when creating the endpoint urls. Defaults to the value of the openeo_version | True |
| OIDC_URL | The URL of the OIDC provider used to authenticate tokens against. | True |
| OIDC_ORGANISATION | The abbreviation of the OIDC provider's organisation name. | True |
| OIDC_ROLES | The OIDC roles to check against when authenticating a user. | False |
| STAC_VERSION | The STAC Version that is being supported by this deployments data discovery endpoints. Defaults to "1.0.0". | False |
| STAC_API_URL | The STAC URL of the catalogue that the application deployment will proxy to. | True |
| STAC_COLLECTIONS_WHITELIST | The collection ids to filter by when proxying to the Stac catalogue. | False |
| POSTGRES_USER | The name of the postgres user. | True |
| POSTGRES_PASSWORD | The pasword for the postgres user. | True |
| POSTGRESQL_HOST | The host the database runs on. | True |
| POSTGRESQL_PORT | The post on the host the database is available on. | True |
| POSTGRES_DB | The name of the databse being used on the host. | True |
| ALEMBIC_DIR | The path to the alembic directory for applying revisions. | True |

## Deploy the application.

1. Revise the database.

python -m revise.py

2. Deploy the uvicorn server

uvicorn openeo_app.main:app --reload
4 changes: 2 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ nav:
- Home: index.md
- Getting Started: setup.md
- User Guide:
- Override endpoints: guide/overriding.md
- Add new endpoints: guide/adding.md
- Manipulating endpoints: guide/registers.md
- Extend the object relational Models: guide/orms.md
- Add your own auth: guide/auth.md
- Extend the object relational Models: guide/orms.md
- Reference:
Expand Down
66 changes: 7 additions & 59 deletions openeo_fastapi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,12 @@
from alembic.config import Config
from pathlib import Path

def get_app_template():
"""
Generate the default app file for an openeo api app.
"""
return """
from fastapi import FastAPI

from openeo_fastapi.api.app import OpenEOApi
from openeo_fastapi.api.types import Billing, FileFormat, GisDataType, Link, Plan
from openeo_fastapi.client.core import OpenEOCore

formats = []

links = []

client = OpenEOCore(
input_formats=formats,
output_formats=formats,
links=links,
billing=Billing(
currency="credits",
default_plan="a-cloud",
plans=[Plan(name="user", description="Subscription plan.", paid=True)],
)
from openeo_fastapi.templates import (
get_app_template,
get_models_template,
get_revision_template
)

api = OpenEOApi(client=client, app=FastAPI())

app = api.app
"""

def get_models_template():
"""
Generate the default models file for an openeo api app.
"""
return """from openeo_fastapi.client.psql.settings import BASE
from openeo_fastapi.client.psql.models import *

metadata = BASE.metadata
"""

def get_revision_template():
"""
Generate the default revision file for the openeo api app.
"""
return """import os
from alembic import command
from alembic.config import Config
from pathlib import Path

from openeo_fastapi.client.psql.settings import DataBaseSettings

settings=DataBaseSettings()

os.chdir(Path(settings.ALEMBIC_DIR))
alembic_cfg = Config("alembic.ini")

command.revision(alembic_cfg, autogenerate=True)
command.upgrade(alembic_cfg, "head")
"""

@click.group()
def cli():
Expand All @@ -85,7 +31,7 @@ def new(path):
else:
path = Path(fs.get_mapper("").root)

openeo_dir = path / "openeo_api"
openeo_dir = path
db_dir = openeo_dir / "psql"
init_file = openeo_dir / "__init__.py"
app_file = openeo_dir / "app.py"
Expand Down Expand Up @@ -121,6 +67,8 @@ def new(path):

revise_file = openeo_dir / "revise.py"
fs.touch(revise_file)
with fs.open(revise_file, 'w') as f:
f.write(get_revision_template())

pass

Expand Down
2 changes: 1 addition & 1 deletion openeo_fastapi/client/psql/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ class DataBaseSettings(BaseSettings):
"""The name of the databse being used on the host."""

ALEMBIC_DIR: Path
"""The path to the alembic directory for applying revisions."""
"""The path leading to the alembic directory to be used."""
2 changes: 0 additions & 2 deletions openeo_fastapi/client/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ class AppSettings(BaseSettings):
"""The domain name hosting the API."""
API_TLS: bool = True
"""Whether the API http scheme should be http or https."""
ALEMBIC_DIR: Path
"""The path leading to the alembic directory to be used."""
API_TITLE: str
"""The API title to be provided to FastAPI."""
API_DESCRIPTION: str
Expand Down
Loading
Loading