Skip to content

API Reference

bear.api

lifespan(app) async

Lifespan event handler for FastAPI to manage startup and shutdown tasks.

Source code in bear/api.py
@asynccontextmanager
async def lifespan(app: FastAPI):
    """Lifespan event handler for FastAPI to manage startup and shutdown tasks."""
    app_state["search_engine"] = SearchEngine()
    yield
    app_state.clear()  # Clear the app state on shutdown

read_root()

Root endpoint to provide instructions for using the API.

Source code in bear/api.py
@app.get("/")
def read_root():
    """Root endpoint to provide instructions for using the API."""
    return {"Instruction": "Try /search_resource?query=your_query_here&top_k=3 or /search_author?query=your_query_here&top_k=3"}

search_resource_route(query=Query(..., title='The query string to search for.'), top_k=Query(3, title='The number of results to return.'), resource_name=Query('work', title='The resource type to search (default: work).'), min_distance=Query(None, title='Minimum distance threshold for results.'), since_year=Query(None, title='Filter results from this year onwards.'))

Search for resources based on the provided query and parameters.

Source code in bear/api.py
@app.get("/search_resource", response_model=list[ResourceSearchResult])
def search_resource_route(
    query: str = Query(..., title="The query string to search for."),
    top_k: int = Query(3, title="The number of results to return."),
    resource_name: str = Query("work", title="The resource type to search (default: work)."),
    min_distance: float | None = Query(None, title="Minimum distance threshold for results."),
    since_year: int | None = Query(None, title="Filter results from this year onwards."),
):
    """Search for resources based on the provided query and parameters."""
    try:
        results = app_state["search_engine"].search_resource(
            resource_name=resource_name, query=query, top_k=top_k, min_distance=min_distance, since_year=since_year
        )

        if not results:
            raise HTTPException(status_code=404, detail="No results found.")

        # Convert results to response format
        formatted_results = []
        for result in results:
            entity = result.get("entity", {})
            # Add abstract from inverted index if available
            abstract = None
            if "abstract_inverted_index" in entity and entity["abstract_inverted_index"]:
                abstract = Work._recover_abstract(entity["abstract_inverted_index"])

            formatted_results.append(
                ResourceSearchResult(
                    id=entity.get("id", ""),
                    doi=entity.get("doi"),
                    title=entity.get("title"),
                    display_name=entity.get("display_name"),
                    publication_year=entity.get("publication_year"),
                    publication_date=entity.get("publication_date"),
                    type=entity.get("type"),
                    cited_by_count=entity.get("cited_by_count"),
                    source_display_name=entity.get("source_display_name"),
                    topics=entity.get("topics", []),
                    abstract=abstract,
                    distance=result.get("distance", 0.0),
                    author_ids=entity.get("author_ids", []),
                )
            )

        return formatted_results

    except HTTPException:
        # Re-raise HTTPExceptions (like 404) without modification
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Search failed: {str(e)}")

search_author_route(query=Query(..., title='The query string to search for authors.'), top_k=Query(3, title='The number of results to return.'), institutions=Query(None, title='Filter authors by institutions.'), min_distance=Query(None, title='Minimum distance threshold for results.'), since_year=Query(None, title='Filter results from this year onwards.'))

Search for authors based on the provided query and parameters.

Source code in bear/api.py
@app.get("/search_author", response_model=list[AuthorSearchResult])
def search_author_route(
    query: str = Query(..., title="The query string to search for authors."),
    top_k: int = Query(3, title="The number of results to return."),
    institutions: list[str] | None = Query(None, title="Filter authors by institutions."),
    min_distance: float | None = Query(None, title="Minimum distance threshold for results."),
    since_year: int | None = Query(None, title="Filter results from this year onwards."),
):
    """Search for authors based on the provided query and parameters."""
    try:
        results = app_state["search_engine"].search_author(
            query=query, top_k=top_k, institutions=institutions, min_distance=min_distance, since_year=since_year
        )

        if not results:
            raise HTTPException(status_code=404, detail="No results found.")

        return [AuthorSearchResult(author_id=result["author_id"], score=result["score"]) for result in results]

    except HTTPException:
        # Re-raise HTTPExceptions (like 404) without modification
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Author search failed: {str(e)}")

Endpoints

The BEAR API provides RESTful endpoints for searching academic resources and authors.

Base URL

http://localhost:8000

Authentication

Currently, no authentication is required for API access.

Response Format

All responses are in JSON format. Successful responses return the requested data, while errors return an error object with a message.

Error Handling

The API uses standard HTTP status codes:

  • 200 OK - Request successful
  • 404 Not Found - No results found
  • 422 Unprocessable Entity - Invalid request parameters
  • 500 Internal Server Error - Server error

Models

ResourceSearchResult

Response model for resource search results.

AuthorSearchResult

Response model for author search results.