Skip to content
Open
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
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.git*
**/*.pyc
.venv/
.venv/
2 changes: 1 addition & 1 deletion .github/workflows/development_dev-research-index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ jobs:
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 }}'
images: 'index.docker.io/${{ secrets.AzureAppService_ContainerUsername_9310ce663981441ab232b6b875b913e2 }}/ccg-research-index:${{ github.sha }}'
2 changes: 1 addition & 1 deletion .github/workflows/main_research-index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ jobs:
app-name: 'research-index'
slot-name: 'production'
publish-profile: ${{ secrets.AzureAppService_PublishProfile_4b15095a06cc4e57aa33f534f4e54311 }}
images: 'index.docker.io/${{ secrets.AzureAppService_ContainerUsername_dce678b65c414723a5c407473fe6c430 }}/ccg-research-index:${{ github.sha }}'
images: 'index.docker.io/${{ secrets.AzureAppService_ContainerUsername_dce678b65c414723a5c407473fe6c430 }}/ccg-research-index:${{ github.sha }}'
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ build/

research_index_backend/
data/
*.bash
*.bash
43 changes: 43 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
exclude: '^docs/conf.py'

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: check-added-large-files
- id: check-ast
- id: check-json
- id: check-merge-conflict
- id: check-xml
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: requirements-txt-fixer
- id: mixed-line-ending
args: ['--fix=auto'] # replace 'auto' with 'lf' to enforce Linux/Mac line endings or 'crlf' for Windows

- repo: https://github.com/pycqa/isort
rev: 7.0.0
hooks:
- id: isort
args: ["--profile", "black", "--filter-files"]

- repo: https://github.com/psf/black
rev: 26.1.0
hooks:
- id: black
language_version: python3

- repo: https://github.com/PyCQA/flake8
rev: 7.3.0
hooks:
- id: flake8
## You can add flake8 plugins via `additional_dependencies`:
# additional_dependencies: [flake8-bugbear]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.19.1 # Use the sha / tag you want to point at
hooks:
- id: mypy
additional_dependencies: ['types-requests']
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ EXPOSE 8000
CMD ["fastapi", "run", "app/main.py", \
"--port", "8000", \
"--workers", "4", \
"--proxy-headers"]
"--proxy-headers"]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Once the VM is up and running, SSH into the VM, download and install memgraph

curl -O https://download.memgraph.com/memgraph/v2.14.1/ubuntu-20.04/memgraph_2.14.1-1_amd64.deb
sudo dpkg -i /memgraph_2.14.1-1_amd64.deb

Set up the Memgraph user to match the credentials specified in the `.env` file.

### 2. Build Docker container
Expand Down
36 changes: 17 additions & 19 deletions app/api/author.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,41 @@
from fastapi import APIRouter, HTTPException, Query, Path
from typing import Annotated
from uuid import UUID

from fastapi import APIRouter, HTTPException, Path, Query

from app.crud.author import Author
from app.schemas.author import AuthorListModel, AuthorOutputModel
from app.schemas.query import FilterWorkstream, FilterParams
from app.schemas.query import FilterParams, FilterWorkstream

router = APIRouter(prefix="/api/authors", tags=["authors"])


@router.get("")
def api_author_list(query: Annotated[FilterWorkstream, Query()]
) -> AuthorListModel:
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):
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:
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)
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")
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
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}") from e
else:
return result

33 changes: 17 additions & 16 deletions app/api/country.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from fastapi import APIRouter, HTTPException, Query, Path
from typing import Annotated

from fastapi import APIRouter, HTTPException, Path, Query

from app.crud.country import Country
from app.schemas.country import CountryList, CountryOutputListModel
from app.schemas.query import FilterBase, FilterParams
Expand All @@ -8,31 +10,30 @@


@router.get("")
def api_country_list(query: Annotated[FilterBase, Query()]
) -> CountryList:
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
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:
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)
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")
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
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}") from e

else:
return result
26 changes: 13 additions & 13 deletions app/api/output.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
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 fastapi import APIRouter, HTTPException, Path, Query
from fastapi.logger import logger

from app.crud.output import Output
from app.schemas.output import OutputListModel, OutputModel
from app.schemas.query import FilterOutputList

router = APIRouter(prefix="/api/outputs", tags=["outputs"])


@router.get("")
def api_output_list(
query: Annotated[FilterOutputList, Query()]
) -> OutputListModel:
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)
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:
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
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
Expand Down
25 changes: 10 additions & 15 deletions app/api/workstream.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
from typing import List, Annotated
from typing import Annotated, List

from fastapi import APIRouter, HTTPException, Query, Path
from fastapi import APIRouter, HTTPException, Path, Query

from app.crud.workstream import Workstream
from app.schemas.workstream import WorkstreamDetailModel, WorkstreamListModel
from app.schemas.query import FilterBase
from app.schemas.workstream import WorkstreamDetailModel, WorkstreamListModel

router = APIRouter(prefix="/api/workstreams", tags=["workstreams"])


@router.get("")
def list_workstreams(
query: Annotated[FilterBase, Query()]) -> WorkstreamListModel:
def list_workstreams(query: Annotated[FilterBase, Query()]) -> WorkstreamListModel:
"""Return a list of workstreams

Returns
Expand All @@ -23,25 +22,21 @@ def list_workstreams(
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
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
"""
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")
raise HTTPException(status_code=404, detail=f"Workstream '{id}' not found")
else:
return results
return results
1 change: 1 addition & 0 deletions app/core/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os

from dotenv import load_dotenv


Expand Down
Loading