Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

With sapi.py (project manager)

Info

Available since version 0.5

On the root of the Search API project execute on the terminal the following command:

Code Block
languagebash
python sapi.py new endpoint <name>

This will generate a bare minimum endpoint with all the steps and changes view on the manual section, and some route examples



Table of Contents

Manual

Use this section if sapi.py is not avialable in your distribution

Adding an Endpoint

1) Create the Endpoint package

  • Create a folder in app/api/v1
  • Inside the folder create the __init__.py and the endpoint file

    Tip

    A descriptive name works the best



On the endpoint file



2) Add the imports

  • Special attention to APIRouter

Code Block
languagepy
themeDJango
from fastapi import APIRouter, Body
from fastapi.requests import Request

3) Declare the endpoint Router

  • This is essentially a small branch of the app, which will hold all our related routes
  • The prefix indicates the prefix of the endpoint

    Info

    All endpoint have the same base path, /es/api/v1, from here we attach the prefix, in this case being /Simple, so /es/api/v1/Simple

Code Block
languagepy
themeDJango
router = APIRouter(prefix='/Simple', tags=['Simple'])

4) Declare the routes

  • At this point, all the routes are pure FastAPI
  • The content of each route depends entirely on the one implementing the endpoint
Tip

If you want more information on how to build routes, and what features are available please go to the FastAPI tutorial, whenever you see @app, just replace that with @router

Code Block
languagepy
themeDJango
@router.post('/post')
async def post_request(req: Request, body: dict = Body()):
    return body

@router.post('/put/{name}')
async def post_request(req: Request, name: str):
    return {"name": name}

@router.post('/get/{id}')
async def post_request(req: Request, id: int, param_a: int = 0):
    return f'GET Request for id {id}, with number {param_a}'
Info

In this scenario the path for each route is:

/es/api/v1/Simple/post

/es/api/v1/Simple/put/lincon

/es/api/v1/Simple/get/42



on the __init__ file



5) Add the import for your router

  • Go to the  __init__.py file
  • Import the router from the API file
Warning

If you don’t import the router in the __init__.py, Search API won’t load it


Code Block
languagepy
themeDJango
from .simple import router

6) Verify Endpoint Status

  • Starting the server check the logs for the entry loading the endpoint
  • In case of error, the logs will show the issue
    • Either unable to load the endpoint or unable to initialize it
    • Otherwise you should see Endpoint <endpoint path> added
  • You can go to /es/docs or /es/redocand check the
    API documentation

Swagger (/es/docs)

ReDoc (/es/redoc)



Endpoint as a Pipeline Wrapper

Using an endpoint to wrap a pipeline gives some advantages when working on a project, specially if a separate team is needs to consume said endpoint, specially when compared to use the provided Pipeline endpoint

General Pipeline Endpoint

  • Pipeline endpoint only accepts POST, without restriction of what parameters can accept
  • User needs to know the parameters each pipeline accepts
  • Proneto data input errors

Specific Pipeline Endpoint

  • FastAPI allow to pass a Pydantic model as the Body, meaning all data validation
  • Multiple methods (GET, PUT, POST, DELET) can apply to same pipeline
  • Can add query parameters or path Parameters
  • Customize pipeline response
  • API documentation & User guidance for data input

How To Use The Pipeline In An API

We will use the Search Endpoint for this example

1) Create a Model

  • Create a file for the model in models/api

    Info

    The __init__.py is already included in this package




on the model file



2) Add the imports

  • Since we are making a model from scratch we need to import BaseModel

Code Block
languagepy
themeDJango
from typing import Optional

from pydantic import BaseModel, Field, Extra

from framework.aggregations.utils import SelectionAgg
from models.engines import SortEntry
from models.utils import BoolOperation

3) Declare the model class

  • All models must inherit from BaseModel or from another model

  • Declare parameters as we did for Stages

Code Block
languagepy
themeDJango
class ApiSearchRequest(BaseModel):
    q: Optional[str] = Field(default='*', description='Query string')
    query: Optional[dict] = Field(default=None, description='Specific query object for search engine')
    knn: Optional[dict] = Field(default=None, description='Specific knn query object for search engine')
    size: Optional[int] = Field(default=25, description='Number of hits to return per request')
    sort: Optional[SortEntry] = Field(description='Sort field and order')
    start:  Optional[int] = Field(alias='from', description='Start position for retrieving hits', ge=0)
    page: Optional[int] = Field(description='Start page for retrieving hits. Minimum page is 1. Not applicable when start, is being used', ge=1)
    fetch_fields: Optional[list[str]] = Field(
        description='List of fields to return in the response based on field values', title='Fetch Fields')
    scroll: Optional[str] = Field(default=None, description='Period to retain the search context for scrolling')
    default_operator: BoolOperation = Field(BoolOperation.OR,
                                            description='The default operator for query string query: AND or OR',
                                            title='Default Operator')
    exclude_fields: Optional[list[str]] = Field(
        description='List of fields to exclude in the response based on field values.', title='Exclude Fields')
    aggs: Optional[list[SelectionAgg]] = Field(
        description='List of selected aggregations. Usable only when a DynamicAggStage exist in the pipeline',
        title='Aggregations')
Note

We will not import the model in the __init__, because we want the route to be import like this

Code Block
from models.api.api_search_request import ApiSearchRequest