-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #60 from ClimateCompatibleGrowth/development
Re-implement app as FastAPI
- Loading branch information
Showing
56 changed files
with
2,296 additions
and
657 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.git* | ||
**/*.pyc | ||
.venv/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy | ||
# More GitHub Actions for Azure: https://github.com/Azure/actions | ||
|
||
name: Build and deploy container app to Azure Web App - dev-research-index | ||
|
||
on: | ||
push: | ||
branches: | ||
- development | ||
workflow_dispatch: | ||
|
||
jobs: | ||
build: | ||
runs-on: 'ubuntu-latest' | ||
|
||
steps: | ||
- name: Checkout the development branch | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
|
||
- name: Log in to registry | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: https://index.docker.io/v1/ | ||
username: ${{ secrets.AzureAppService_ContainerUsername_9310ce663981441ab232b6b875b913e2 }} | ||
password: ${{ secrets.AzureAppService_ContainerPassword_a6a4cadc786e40478e1d15d558c66044 }} | ||
|
||
- name: Build and push container image to registry | ||
uses: docker/build-push-action@v3 | ||
with: | ||
push: true | ||
tags: index.docker.io/${{ secrets.AzureAppService_ContainerUsername_9310ce663981441ab232b6b875b913e2 }}/ccg-research-index:${{ github.sha }} | ||
file: ./Dockerfile | ||
|
||
deploy: | ||
runs-on: ubuntu-latest | ||
needs: build | ||
environment: | ||
name: 'production' | ||
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} | ||
|
||
steps: | ||
- name: Deploy to Azure Web App | ||
id: deploy-to-webapp | ||
uses: azure/webapps-deploy@v2 | ||
with: | ||
app-name: 'dev-research-index' | ||
slot-name: 'production' | ||
publish-profile: ${{ secrets.AzureAppService_PublishProfile_a74f0a22a9c3465a91fa629137af0f81 }} | ||
images: 'index.docker.io/${{ secrets.AzureAppService_ContainerUsername_9310ce663981441ab232b6b875b913e2 }}/ccg-research-index:${{ github.sha }}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,16 @@ | ||
# Use an official Python runtime as a parent image | ||
FROM python:3.11.7-bookworm | ||
|
||
# Set the working directory in the container to /app | ||
WORKDIR /app | ||
WORKDIR /research-index | ||
|
||
# Add the current directory contents into the container at /app | ||
ADD ./app /app | ||
ADD requirements.txt /app/requirements.txt | ||
ADD requirements.txt requirements.txt | ||
|
||
# Install packages for the memgraph client | ||
RUN apt update -y | ||
RUN apt install -y python3-dev cmake make gcc g++ libssl-dev | ||
|
||
# Install any needed packages specified in requirements.txt | ||
RUN pip install --no-cache-dir -r requirements.txt | ||
|
||
# Make port 80 available to the world outside this container | ||
EXPOSE 80 | ||
ADD . . | ||
|
||
EXPOSE 8000 | ||
|
||
CMD ["gunicorn", "--bind", "0.0.0.0:80", "app:app"] | ||
CMD ["fastapi", "run", "app/main.py", \ | ||
"--port", "8000", \ | ||
"--workers", "4", \ | ||
"--proxy-headers"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from fastapi import APIRouter, HTTPException, Query, Path | ||
from typing import Annotated | ||
from uuid import UUID | ||
|
||
from app.crud.author import Author | ||
from app.schemas.author import AuthorListModel, AuthorOutputModel | ||
from app.schemas.query import FilterWorkstream, FilterParams | ||
|
||
router = APIRouter(prefix="/api/authors", tags=["authors"]) | ||
|
||
|
||
@router.get("") | ||
def api_author_list(query: Annotated[FilterWorkstream, Query()] | ||
) -> AuthorListModel: | ||
try: | ||
authors = Author() | ||
if result := authors.get_authors(skip=query.skip, | ||
limit=query.limit, | ||
workstream=query.workstream): | ||
return result | ||
except Exception as e: | ||
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}") from e | ||
|
||
@router.get("/{id}") | ||
def api_author(id: Annotated[UUID, Path(title="Unique author identifier")], | ||
query: Annotated[FilterParams, Query()] | ||
) -> AuthorOutputModel: | ||
author = Author() | ||
try: | ||
result = author.get_author(id=id, | ||
result_type=query.result_type, | ||
skip=query.skip, | ||
limit=query.limit) | ||
|
||
except KeyError: | ||
raise HTTPException(status_code=404, | ||
detail=f"Author '{id}' not found") | ||
except ValueError as e: | ||
raise HTTPException(status_code=500, | ||
detail=f"Database error: {str(e)}") from e | ||
else: | ||
return result | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from fastapi import APIRouter, HTTPException, Query, Path | ||
from typing import Annotated | ||
from app.crud.country import Country | ||
from app.schemas.country import CountryList, CountryOutputListModel | ||
from app.schemas.query import FilterBase, FilterParams | ||
|
||
router = APIRouter(prefix="/api/countries", tags=["countries"]) | ||
|
||
|
||
@router.get("") | ||
def api_country_list(query: Annotated[FilterBase, Query()] | ||
) -> CountryList: | ||
country_model = Country() | ||
try: | ||
return country_model.get_countries(query.skip, query.limit) | ||
except Exception as e: | ||
raise HTTPException(status_code=500, | ||
detail=f"Server error: {str(e)}") from e | ||
|
||
@router.get("/{id}") | ||
def api_country(id: Annotated[str, Path(examples=['KEN'], title="Country identifier", pattern="^([A-Z]{3})$")], | ||
query: Annotated[FilterParams, Query()] | ||
) -> CountryOutputListModel: | ||
country_model = Country() | ||
try: | ||
result = country_model.get_country(id, | ||
query.skip, | ||
query.limit, | ||
query.result_type) | ||
except KeyError: | ||
raise HTTPException(status_code=404, | ||
detail=f"Country with id {id} not found") | ||
except ValueError as e: | ||
raise HTTPException(status_code=500, | ||
detail=f"Database error: {str(e)}") from e | ||
|
||
else: | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from fastapi import APIRouter, HTTPException, Query, Path | ||
from fastapi.logger import logger | ||
from typing import Annotated | ||
from app.schemas.query import FilterOutputList | ||
from uuid import UUID | ||
|
||
from app.crud.output import Output | ||
from app.schemas.output import OutputListModel, OutputModel | ||
|
||
router = APIRouter(prefix="/api/outputs", tags=["outputs"]) | ||
|
||
|
||
@router.get("") | ||
def api_output_list( | ||
query: Annotated[FilterOutputList, Query()] | ||
) -> OutputListModel: | ||
"""Return a list of outputs""" | ||
outputs = Output() | ||
try: | ||
return outputs.get_outputs(query.skip, | ||
query.limit, | ||
query.result_type, | ||
query.country) | ||
except ValueError as e: | ||
raise HTTPException(status_code=500, detail=str(e)) from e | ||
|
||
|
||
@router.get("/{id}") | ||
def api_output(id: Annotated[UUID, Path(title="Unique output identifier")]) -> OutputModel: | ||
output = Output() | ||
try: | ||
result = output.get_output(id) | ||
except KeyError as e: | ||
raise HTTPException( | ||
status_code=404, detail=f"Output with id {id} not found" | ||
) from e | ||
except Exception as e: | ||
logger.error(f"Error in api_output: {str(e)}") | ||
raise HTTPException(status_code=400, detail=str(e)) from e | ||
else: | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from typing import List | ||
|
||
from fastapi import APIRouter | ||
|
||
from app.schemas.topic import TopicBaseModel | ||
|
||
router = APIRouter(prefix="/api/topics", tags=["countries"]) | ||
|
||
|
||
@router.get("") | ||
def api_topics_list() -> List[TopicBaseModel]: | ||
raise NotImplementedError("Have not yet implemented topics in the database") | ||
|
||
|
||
@router.get("/{id}") | ||
def api_topics_list(id: str) -> TopicBaseModel: | ||
raise NotImplementedError("Have not yet implemented topics in the database") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from typing import List, Annotated | ||
|
||
from fastapi import APIRouter, HTTPException, Query, Path | ||
|
||
from app.crud.workstream import Workstream | ||
from app.schemas.workstream import WorkstreamDetailModel, WorkstreamListModel | ||
from app.schemas.query import FilterBase | ||
|
||
router = APIRouter(prefix="/api/workstreams", tags=["workstreams"]) | ||
|
||
|
||
@router.get("") | ||
def list_workstreams( | ||
query: Annotated[FilterBase, Query()]) -> WorkstreamListModel: | ||
"""Return a list of workstreams | ||
Returns | ||
------- | ||
app.schemas.workstream.WorkstreamListModel | ||
""" | ||
model = Workstream() | ||
try: | ||
results = model.get_all(skip=query.skip, limit=query.limit) | ||
except KeyError as e: | ||
raise HTTPException(status_code=500, | ||
detail=f"Database error: {str(e)}") from e | ||
else: | ||
return results | ||
|
||
|
||
|
||
@router.get("/{id}") | ||
def get_workstream( | ||
id: Annotated[str, Path(title="Unique workstream identifier")], | ||
query: Annotated[FilterBase, Query()] | ||
) -> WorkstreamDetailModel: | ||
"""Return a single workstream | ||
""" | ||
model = Workstream() | ||
try: | ||
results = model.get(id, skip=query.skip, limit=query.limit) | ||
except KeyError: | ||
raise HTTPException(status_code=404, | ||
detail=f"Workstream '{id}' not found") | ||
else: | ||
return results |
Oops, something went wrong.