Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.0.0 #74

Merged
merged 40 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d8cc054
improve query performance by avoiding unnecessary joins
GalMunGral Sep 18, 2023
00e8269
fix linting
Rashmil-1999 Sep 20, 2023
f16ee94
update checkout action version
Rashmil-1999 Sep 20, 2023
2c148b3
update checkout action version
Rashmil-1999 Sep 20, 2023
b88ab5a
update checkout action version
Rashmil-1999 Sep 20, 2023
958d44a
update checkout action version
Rashmil-1999 Sep 20, 2023
9d9fdbf
update checkout action version
Rashmil-1999 Sep 20, 2023
98bbdf1
update checkout action version
Rashmil-1999 Sep 20, 2023
4021eb3
update checkout action version
Rashmil-1999 Sep 20, 2023
8903862
update checkout action version
Rashmil-1999 Sep 20, 2023
c9a7481
update checkout action version
Rashmil-1999 Sep 20, 2023
b24044a
update checkout action version
Rashmil-1999 Sep 20, 2023
08eaed1
update checkout action version
Rashmil-1999 Sep 20, 2023
59d473b
fix typo
Rashmil-1999 Sep 20, 2023
a0a4e28
try poetry 1.4.2
Rashmil-1999 Sep 20, 2023
38946dc
fix lock-file and update actions
Rashmil-1999 Sep 27, 2023
d2fad8a
Merge pull request #65 from Oceans-1876/station-query-optimization
Rashmil-1999 Sep 27, 2023
822f621
Fix pytest workflow failure (#67)
Rashmil-1999 Oct 2, 2023
18e081e
Station groups (#68)
GalMunGral Oct 4, 2023
2ccbe91
update fonts submodule
Rashmil-1999 Oct 4, 2023
6c442e7
update fonts submodule (#69)
Rashmil-1999 Oct 4, 2023
8397c81
Merge branch 'develop' of https://github.com/Oceans-1876/challenger-a…
Rashmil-1999 Oct 9, 2023
33db278
data update
Rashmil-1999 Oct 17, 2023
6097e42
add station filter to fuzzymatch endpoint (#71)
GalMunGral Oct 18, 2023
094ee11
replace string similarity function
GalMunGral Oct 18, 2023
8811106
Merge branch 'develop' of https://github.com/Oceans-1876/challenger-a…
Rashmil-1999 Oct 18, 2023
e2beb3d
Merge pull request #72 from Oceans-1876/fuzzymatch-optimization
Rashmil-1999 Oct 18, 2023
043f500
filter species at api endpoints
GalMunGral Oct 26, 2023
b961917
add a None-check
GalMunGral Oct 27, 2023
02da08e
Merge pull request #73 from Oceans-1876/species-filter
Rashmil-1999 Oct 30, 2023
fe6f85a
Merge branch 'develop' of https://github.com/Oceans-1876/challenger-a…
Rashmil-1999 Nov 2, 2023
01cab8a
prepare for release
GalMunGral Dec 4, 2023
06c9659
update CONTRIBUTORS.md
GalMunGral Dec 4, 2023
0668502
sort names alphabetically
GalMunGral Dec 4, 2023
5f54622
update changelog
Rashmil-1999 Dec 6, 2023
5d7bcd6
update documentation
GalMunGral Dec 6, 2023
978a4b5
trigger pytest action on PR updates
GalMunGral Dec 6, 2023
f106420
Add version to workflow (#75)
Rashmil-1999 Dec 12, 2023
29aa2d7
Merge branch 'develop' of https://github.com/Oceans-1876/challenger-a…
Rashmil-1999 Dec 12, 2023
613941b
Merge branch 'develop' into release-1.0.0
Rashmil-1999 Dec 12, 2023
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
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