Skip to content

Commit

Permalink
Merge pull request #74 from Oceans-1876/release-1.0.0
Browse files Browse the repository at this point in the history
Release 1.0.0
  • Loading branch information
Rashmil-1999 authored Dec 12, 2023
2 parents 0c4a728 + 613941b commit fbcce8f
Show file tree
Hide file tree
Showing 18 changed files with 1,623 additions and 1,485 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
steps:
# Checkout source code
- name: Check out source code
uses: actions/checkout@v2
uses: actions/checkout@v4

# Calculate some variables that are used later
- name: Version information
Expand All @@ -29,7 +29,7 @@ jobs:
fi
echo "GITHUB_BRANCH=${BRANCH}" >> $GITHUB_ENV
if [ "$BRANCH" == "main" ]; then
version=$(cat package.json | grep \"version\" | head -1 | awk -F= "{ print $2 }" | sed 's/[version:,",]//g' | tr -d '[[:space:]]')
version=$(awk -F= '/^version/ { print $2}' pyproject.toml | sed 's/[ "]//g')
tags="latest"
oldversion=""
while [ "${oldversion}" != "${version}" ]; do
Expand All @@ -52,6 +52,7 @@ jobs:
uses: elgohr/[email protected]
env:
BRANCH: ${{ env.GITHUB_BRANCH }}
VERSION: ${{ env.VERSION }}
BUILDNUMBER: ${{ github.run_number }}
GITSHA1: ${{ github.sha }}
with:
Expand All @@ -60,7 +61,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
registry: ghcr.io
tags: "${{ env.TAGS }}"
buildargs: BRANCH,BUILDNUMBER,GITSHA1
buildargs: BRANCH,VERSION,BUILDNUMBER,GITSHA1
dockerfile: docker/Dockerfile

- name: Deploy to prod server
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ name: Perform Type and Formatting checks on a new/edited pull requests.
on:
workflow_dispatch:
pull_request:
types: [opened, edited]
types: [opened, edited, synchronize]

jobs:
perfrom-type-and-formatting-check:
runs-on: ubuntu-latest
perform-type-and-formatting-check:
runs-on: ubuntu-20.04

steps:
- name: Check out repo
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup Python 3.10
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: "3.10"

Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Run unit test
on:
workflow_dispatch:
pull_request:
types: [ opened, edited ]
types: [opened, edited, synchronize]

jobs:
pytest:
Expand Down Expand Up @@ -37,7 +37,7 @@ jobs:
steps:
- name: Check out repo
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: true

Expand Down Expand Up @@ -68,3 +68,4 @@ jobs:
POSTGRES_DB: challenger_expedition
FIRST_SUPERUSER: [email protected]
FIRST_SUPERUSER_PASSWORD: secret_password
SECRET_KEY: pytest_secret_key
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
repos:
- repo: https://github.com/PyCQA/isort
rev: 5.10.1
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/python/black
rev: 22.6.0
hooks:
- id: black
- repo: https://gitlab.com/pycqa/flake8
- repo: https://github.com/pycqa/flake8
rev: 5.0.4
hooks:
- id: flake8
Expand Down
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0] - 2023-12-04

### Added

- Added Roboto Bold font (in `fonts` submodule).

### Fixed

- Optimized station search.
- Fixed pytest workflow failure.

### Changed

- Added temporary binomial name filter at species endpoints.
- Replaced string similarity function for fuzzy search.
- Minor changes to several API endpoints.

## [0.1.0] - 2022-12-21

- The initial release of the Challenger-API.
8 changes: 8 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Contributors

- Chris Navarro
- Kaveh Karimi-Asli
- Rashmil Panchani
- Michael Wieck-Sosa
- Olajide Jegede
- Wenqi He
34 changes: 27 additions & 7 deletions app/api/v1/endpoints/species.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from typing import Any, List, Optional, Union
from typing import Any, List, Optional, Type, Union

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import Table
from sqlalchemy.orm import Session

from app import crud, schemas
from app.api import deps
from app.models import SpeciesCommonNames, SpeciesSynonyms
from app.db.base_class import Base
from app.models import SpeciesCommonNames, SpeciesSynonyms, stations_species_table
from app.utils.species import binomial_only

router = APIRouter()

Expand All @@ -28,7 +31,7 @@ def read_all_species(
) -> Any:
"""Retrieve all species."""
species = crud.species.get_all(db, order_by=order_by)
return species
return binomial_only(species)


@router.post("/search/", response_model=List[schemas.SpeciesSummary])
Expand All @@ -45,14 +48,15 @@ def read_species_by_search(
order_by=order_by,
limit=limit,
)
return species
return binomial_only(species)


@router.get("/fuzzymatch/", response_model=List[schemas.SpeciesSummary])
def read_fuzzy_species_by_search(
query_str: str,
station: Optional[str] = Query(None),
db: Session = Depends(deps.get_db),
min_string_similarity_score: float = 0.2,
min_string_similarity_score: float = 0.5,
limit: int = 0,
order_by: Optional[List[str]] = Query(None),
) -> Any:
Expand Down Expand Up @@ -91,17 +95,33 @@ def read_fuzzy_species_by_search(
],
}

relations: List[Union[Type[Base], Table]] = [SpeciesCommonNames, SpeciesSynonyms]

if station:
expressions_dict = {
"join": "AND",
"expressions": [
expressions_dict,
{
"column_name": "station_id",
"search_term": station,
"operator": "eq",
},
],
}
relations.append(stations_species_table)

expressions = schemas.ExpressionGroup(**expressions_dict)

"""Retrieves the species based on the given search expressions."""
species = crud.species.search(
db,
expressions=expressions,
relations=[SpeciesCommonNames, SpeciesSynonyms],
relations=relations,
order_by=order_by,
limit=limit,
)
return species
return binomial_only(species)


@router.get(
Expand Down
9 changes: 7 additions & 2 deletions app/api/v1/endpoints/stations.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from typing import Any, List, Optional, Union
from typing import Any, List, Optional, Type, Union

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import Table
from sqlalchemy.orm import Session

from app import crud, schemas
from app.api import deps
from app.db.base_class import Base
from app.models import stations_species_table

router = APIRouter()
Expand Down Expand Up @@ -40,10 +42,13 @@ def read_stations_by_search(
order_by: Optional[List[str]] = Query(None),
) -> Any:
"""Retrieves the stations based on the given search expressions."""
relations: Optional[List[Union[Type[Base], Table]]] = (
[stations_species_table] if expressions.uses_column("species_id") else None
)
stations = crud.station.search(
db,
expressions=expressions,
relations=[stations_species_table],
relations=relations,
order_by=order_by,
limit=limit,
)
Expand Down
8 changes: 7 additions & 1 deletion app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def get_emails_enabled(cls, v: bool, values: Dict[str, Any]) -> bool:
and values.get("EMAILS_FROM_EMAIL")
)

EMAIL_TEST_USER: EmailStr = "test@example.com" # type: ignore
EMAIL_TEST_USER: EmailStr = "test2@example.com" # type: ignore
FIRST_SUPERUSER: Optional[EmailStr] = None
FIRST_SUPERUSER_PASSWORD: Optional[str] = None

Expand All @@ -122,6 +122,12 @@ def get_superuser_password(cls, v: Optional[str]) -> Optional[str]:
return "test"
return v

@validator("ENABLE_AUTH", pre=True)
def get_auth_enable(cls, v: Optional[bool]) -> Optional[bool]:
if os.environ.get("PYTHON_TEST"):
return True
return v

USERS_OPEN_REGISTRATION: bool = False

class Config:
Expand Down
6 changes: 3 additions & 3 deletions app/crud/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ def create_search_expressions(
raise ValueError(f"Invalid column name: {expression.column_name}")

if column.type.python_type == str and expression.fuzzy: # type: ignore
similarity_func = func.similarity(column, expression.search_term)
# TODO: find a better searching function in database.
# similarity_func = func.levenshtein(column, expression.search_term)

similarity_func = func.word_similarity(expression.search_term, column)

search_expressions["clauses"].append(
cast(
BinaryExpression,
Expand Down
10 changes: 8 additions & 2 deletions app/crud/crud_station.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
from typing import Any, Optional
from typing import Any, Optional, cast

from sqlalchemy.orm import Session

from app.crud.base import CRUDBase
from app.models import Station
from app.schemas import StationCreate, StationSummaryPagination, StationUpdate
from app.utils.species import binomial_only


class CRUDStation(
CRUDBase[Station, StationCreate, StationUpdate, StationSummaryPagination]
):
def get(self, db: Session, id: Any) -> Optional[Station]:
return db.query(self.model).filter(self.model.name == id).first()
station = cast(
Station, db.query(self.model).filter(self.model.name == id).first()
)
if station:
station.species = binomial_only(station.species)
return station


station = CRUDStation(Station)
9 changes: 9 additions & 0 deletions app/schemas/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class Expression(BaseModel):
fuzzy: bool = False
min_string_similarity: Optional[float] = Field(default=0.1)

def uses_column(self, name: str) -> bool:
return self.column_name == name


class ExpressionGroup(BaseModel):
join: Optional[Join]
Expand All @@ -46,5 +49,11 @@ def expressions_validator(
raise ValueError("a join operator is not needed for one expression")
return v

def uses_column(self, name: str) -> bool:
for expression in self.expressions:
if expression.uses_column(name):
return True
return False


ExpressionGroup.update_forward_refs()
4 changes: 4 additions & 0 deletions app/schemas/station.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class StationBase(BaseModel):
name: str
date: date
coordinates: List[float] = Field(min_items=2, max_items=2)
fao_area: int
location: str
gear: Optional[str]
sediment_sample: Optional[str]

@validator("coordinates", pre=True)
def to_point(cls, value: WKBElement) -> List[float]:
Expand Down
17 changes: 17 additions & 0 deletions app/utils/species.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import List

from app.models import Species


def binomial_only(species: List[Species]) -> List[Species]:
"""
TODO: This is a temporary fix. In the future, we could consider filtering out genera
when loading data into the database or as part of the OCR workflow.
"""
# Unlike `current_name`, `current_canonical_full_name` doesn't include
# author(s) and year of publication, so for a genus, there won't be any spaces.
return [
sp
for sp in species
if sp.current_canonical_simple_name and " " in sp.current_canonical_simple_name
]
2 changes: 1 addition & 1 deletion fonts
Submodule fonts updated 256 files
Loading

0 comments on commit fbcce8f

Please sign in to comment.