From fbf4529323fba77f536aa7d4badeff1d68ebe1aa Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Mon, 5 Feb 2024 23:45:19 +0100 Subject: [PATCH 01/10] Improved error handling in views endpoints --- pephub/routers/api/v1/project.py | 5 +++-- requirements/requirements-all.txt | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pephub/routers/api/v1/project.py b/pephub/routers/api/v1/project.py index e8220044..949bc025 100644 --- a/pephub/routers/api/v1/project.py +++ b/pephub/routers/api/v1/project.py @@ -27,6 +27,7 @@ ProjectNotFoundError, ViewAlreadyExistsError, SampleAlreadyExistsError, + SampleNotInViewError, ) from pepdbagent.models import ( AnnotationModel, @@ -896,7 +897,7 @@ async def create_view_of_the_project( _LOGGER.error(f"Could not create view. Error: {e}") raise HTTPException( status_code=409, - detail="Could not create view. Server error", + detail="Could not create view", ) return JSONResponse( content={ @@ -1006,7 +1007,7 @@ def delete_sample_from_view( view_name=view, sample_name=sample_name, ) - except SampleNotFoundError: + except SampleNotInViewError: raise HTTPException( status_code=404, detail=f"Sample '{sample_name}' not found in view '{view}'", diff --git a/requirements/requirements-all.txt b/requirements/requirements-all.txt index 0774b1de..48ed2544 100644 --- a/requirements/requirements-all.txt +++ b/requirements/requirements-all.txt @@ -1,6 +1,7 @@ fastapi>=0.108.0 psycopg>=3.1.15 -pepdbagent @ git+https://github.com/pepkit/pepdbagent.git@dev#egg=pepdbagent +# pepdbagent @ git+https://github.com/pepkit/pepdbagent.git@dev#egg=pepdbagent +pepdbagent>=0.7.3 peppy>=0.40.1 eido>=0.2.2 jinja2>=3.1.2 From 86174053377101dc95ff3e2c9c3981b5327c33ae Mon Sep 17 00:00:00 2001 From: Nathan LeRoy Date: Tue, 6 Feb 2024 15:11:23 -0500 Subject: [PATCH 02/10] update docs links --- web/src/components/layout/nav/nav-desktop.tsx | 14 ++++---------- web/src/components/layout/nav/nav-mobile.tsx | 12 ++++-------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/web/src/components/layout/nav/nav-desktop.tsx b/web/src/components/layout/nav/nav-desktop.tsx index 15c0eeb3..98376a0b 100644 --- a/web/src/components/layout/nav/nav-desktop.tsx +++ b/web/src/components/layout/nav/nav-desktop.tsx @@ -133,26 +133,20 @@ export const NavDesktop = () => { -
  • - - - API docs - -
  • - + GitHub
  • - Validation + Validation
  • - - About + + Docs
  • diff --git a/web/src/components/layout/nav/nav-mobile.tsx b/web/src/components/layout/nav/nav-mobile.tsx index bf418ab1..0c0ce940 100644 --- a/web/src/components/layout/nav/nav-mobile.tsx +++ b/web/src/components/layout/nav/nav-mobile.tsx @@ -82,10 +82,6 @@ export const MobileNav = () => { )} - - - API docs - GitHub @@ -94,14 +90,14 @@ export const MobileNav = () => { Validation - - - About - Search + + + Docs + {user ? ( From 4faa04672b1b4d8d5ccc452c5fdfee4c9aedbedd Mon Sep 17 00:00:00 2001 From: Nathan LeRoy Date: Tue, 6 Feb 2024 15:11:43 -0500 Subject: [PATCH 03/10] remove about page --- web/src/main.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/web/src/main.tsx b/web/src/main.tsx index f34fa5e4..bfab7198 100644 --- a/web/src/main.tsx +++ b/web/src/main.tsx @@ -41,10 +41,6 @@ const router = createBrowserRouter([ path: '/', element: , }, - { - path: '/about', - element: , - }, { path: '/search', element: , From 9c978279e3808b31d73453cf998bc4e4bc9da491 Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Thu, 8 Feb 2024 02:40:57 +0100 Subject: [PATCH 04/10] Added namespace stats endpoint --- pephub/routers/api/v1/namespace.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pephub/routers/api/v1/namespace.py b/pephub/routers/api/v1/namespace.py index 9fb27ef4..f1ee0d3d 100644 --- a/pephub/routers/api/v1/namespace.py +++ b/pephub/routers/api/v1/namespace.py @@ -24,7 +24,12 @@ ProjectNotInFavorites, ) from pepdbagent.const import DEFAULT_LIMIT_INFO -from pepdbagent.models import ListOfNamespaceInfo, Namespace, AnnotationList +from pepdbagent.models import ( + ListOfNamespaceInfo, + Namespace, + AnnotationList, + NamespaceStats, +) from typing import Literal from typing_extensions import Annotated @@ -440,3 +445,15 @@ async def get_namespace_information( agent: PEPDatabaseAgent = Depends(get_db), ) -> ListOfNamespaceInfo: return agent.namespace.info(limit=limit) + + +@namespaces.get( + "/stats", + summary="Get statistics about each namespace", + response_model=NamespaceStats, +) +async def get_namespace_information( + agent: PEPDatabaseAgent = Depends(get_db), + namespace: Optional[str] = None, +): + return agent.namespace.stats(namespace=namespace) From fbd2911d0d702a75ae68188d6067b7d6e04b95ee Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Thu, 8 Feb 2024 21:28:53 +0100 Subject: [PATCH 05/10] work on #293 --- web/src/components/tables/sample-table.tsx | 7 +++++++ web/src/globals.css | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/web/src/components/tables/sample-table.tsx b/web/src/components/tables/sample-table.tsx index 5ecc3ce4..38055c03 100644 --- a/web/src/components/tables/sample-table.tsx +++ b/web/src/components/tables/sample-table.tsx @@ -1,5 +1,6 @@ import { HotTable } from '@handsontable/react'; import { FC } from 'react'; +import Handsontable from 'handsontable'; import { Sample } from '../../../types'; import { arraysToSampleList, sampleListToArrays } from '../../utils/sample-table'; @@ -44,6 +45,12 @@ export const SampleTable: FC = ({ data, readOnly = false, onChange, heigh height={height || tableHeight} readOnly={readOnly} colHeaders={true} + colWidths={200} + rowHeights={23} + renderer={(instance, td, row, col, prop, value, cellProperties) => { + Handsontable.renderers.TextRenderer.apply(this, [instance, td, row, col, prop, value, cellProperties]); + td.innerHTML = `
    ${value || '' }
    ` + }} dropdownMenu={true} hiddenColumns={{ indicators: true, diff --git a/web/src/globals.css b/web/src/globals.css index ed989dcf..13fd74cf 100644 --- a/web/src/globals.css +++ b/web/src/globals.css @@ -532,3 +532,9 @@ body { .list-none { list-style: none; } + +.handsontable .truncated { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} \ No newline at end of file From 04cea1872ad1d1a5cda18e1ebf84db4d489a56b8 Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Thu, 8 Feb 2024 21:57:37 +0100 Subject: [PATCH 06/10] updated readme --- README.md | 187 ++++-------------------------------------------------- 1 file changed, 12 insertions(+), 175 deletions(-) diff --git a/README.md b/README.md index 37c0349d..aae9b8b8 100644 --- a/README.md +++ b/README.md @@ -1,185 +1,22 @@ - +

    +

    -# pephub +

    + PEPhub +

    -**pephub** is a biological metadata server that lets you view, store, and share your sample metadata in form of [PEPs](https://pep.databio.org/en/latest/). It has 3 components: 1) a _database_ where PEPs are stored; 2) an _API_ to programmatically read and write PEPs in the database; and 3) a web-based _user interface_ to view and manage these PEPs via a front-end. +**PEPhub** is a biological metadata server that lets you view, store, and share your sample metadata in form of [PEPs](https://pep.databio.org/en/latest/). It has 3 components: 1) a _database_ where PEPs are stored; 2) an _API_ to programmatically read and write PEPs in the database; and 3) a web-based _user interface_ to view and manage these PEPs via a front-end. -## Organization +--- -## Setting up a development environment +**Deployed public instance**: https://pephub.databio.org/ -PEPhub consists of 3 components: 1) A postgres database; 2) the PEPhub API; 3) the PEPhub UI. +**API**: https://pephub-api.databio.org/api/v1/docs -### 1. Database setup +**Documentation**: https://pep.databio.org/pephub -_pephub_ stores PEPs in a [POSTGRES](https://www.postgresql.org/) database. Create a new pephub-compatible postgres instance locally: +**Source Code**: https://github.com/pepkit/pephub -``` -docker pull postgres -docker run \ - -e POSTGRES_USER=postgres \ - -e POSTGRES_PASSWORD=docker \ - -e POSTGRES_DB=pep-db \ - -p 5432:5432 \ - postgres -``` +--- -You should now have a pephub-compatible postgres instance running at http://localhost:5432. -You can use [load_db.py](scripts/load_db.py) to load a directory of PEPs into the database. - -### 2. `pephub` API setup - -#### Install - -Install dependencies using `pip` (_We suggest using virtual environments_): - -``` -python -m venv venv && source venv/bin/activate -pip install -r requirements/requirements-all.txt -``` - -#### Running - -_pephub_ may be run in several ways. In every case, pephub requires configuration. Configuration settings are supplied to pephub through environment variables. The following settings are **required**. While pephub has built-in defaults for these settings, you should provide them to ensure compatability: - -- `POSTGRES_HOST`: The hostname of the PEPhub database server -- `POSTGRES_DB`: The name of the database inside the postgres server -- `POSTGRES_USER`: Username for the database -- `POSTGRES_PASSWORD`: Password for the user -- `POSTGRES_PORT`: Port for postgres database -- `GH_CLIENT_ID`: Client ID for the GitHub application that authenticates users -- `GH_CLIENT_SECRET`: Client secret for the GitHub application that authenticates users -- `BASE_URI`: A BASE URI of the PEPhub (e.g. localhost:8000) - -You must set these environment variables prior to running PEPhub. We've provided `env` files inside [`environment`](./environment) which you may `source` to load your environment. Alternatively, you may store them locally in a `.env` file. This file will get loaded and exported to your environment when the server starts up. We've included an [example](environment/template.env) `.env` file with this repository. You can read more about server settings and configuration [here](docs/server-settings.md). - -Once the configuration variables are set, run pephub natively with: - -``` -uvicorn pephub.main:app --reload -``` - -The _pephub_ API should now be running at http://localhost:8000. - -### 3. React PEPhub UI setup - -_Important:_ To make the development server work, you must include a `.env.local` file inside `web/` with the following contents: - -``` -VITE_API_HOST=http://localhost:8000 -``` - -This ensures that the frontend development server will proxy requests to the backend server. You can now run the frontend development server: - -```bash -cd web -npm install # yarn install -npm start # yarn dev -``` - -The pephub frontend development server should now be running at http://localhost:5173/. - -### 3. (_Optional_) GitHub Authentication Client Setup - -_pephub_ uses GitHub for namespacing and authentication. As such, a GitHub application capable of logging in users is required. We've included [instructions for setting up GitHub authentication locally](https://github.com/pepkit/pephub/blob/master/docs/authentication.md#setting-up-github-oauth-for-your-own-server) using your own GitHub account. - -### 4. (_Optional_) Vector Database Setup - -We've added [semantic-search](https://huggingface.co/course/chapter5/6?fw=tf#using-embeddings-for-semantic-search) capabilities to pephub. Optionally, you may host an instance of the [qdrant](https://qdrant.tech/) **vector database** to store embeddings computed using a sentence transformer that has mined and processed any relevant metadata from PEPs. If no qdrant connection settings are supplied, pephub will default to SQL search. Read more [here](docs/semantic-search.md). To run qdrant locally, simply run the following: - -``` -docker pull qdrant/qdrant -docker run -p 6333:6333 \ - -v $(pwd)/qdrant_storage:/qdrant/storage \ - qdrant/qdrant -``` - -## Running with docker: - -### Option 1. Standalone `docker`: - -If you already have a public database instance running, you can choose to build and run the server container only. **A note to Apple Silicon (M1/M2) users**: If you have issues running, try setting your default docker platform with `export DOCKER_DEFAULT_PLATFORM=linux/amd64` to get the container to build and run properly. See [this issue](https://github.com/pepkit/pephub/issues/87) for more information. - -**1. Environment:** -Ensure that you have your [environment](docs/server-settings.md) properly configured. To manage secrets in your environment, we leverage `pass` and curated [`.env` files](environment/production.env). You can use our `launch_docker.sh` script to start your container with these `.env` files. - -**2. Build and start container:** - -``` -docker build -t pephub . -./launch_docker.sh - -``` - -Alternatively, you can inject your environment variables one-by-one: - -``` - -docker run -p 8000:8000 \ - -e POSTGRES_HOST=localhost \ - -e POSTGRES_DB=pep-db \ - ... -pephub - -``` - -Or, provide your own `.env` file: - -``` - -docker run -p 8000:8000 \ - --env-file path/to/.env \ - pephub - -``` - -### Option 2. `docker compose`: - -The server has been Dockerized and packaged with a [postgres](https://hub.docker.com/_/postgres) image to be run with [`docker compose`](https://docs.docker.com/compose/). This lets you run everything at once and develop without having to manage database instances. - -You can start a development environment in two steps: - -**1. Curate your environment:** -Since we are running in `docker`, we need to supply environment variables to the container. The `docker-compose.yaml` file is written such that you can supply a `.env` file at the root with your configurations. See the [example env file](environment/template.env) for reference. See [here](docs/server-settings.md) for a detailed explanation of all configurable server settings. For now, you can simply copy the `env` file: - -``` -cp environment/template.env .env -``` - -**2. Build and start the containers:** - -```console -docker compose up --build -``` - -`pephub` now runs/listens on http://localhost:8000 -`postgres` now runs/listens on http://localhost:5432 - -**3. (_Optional_) Utilize the [`load_db`](scripts/load_db.py) script to populate the database with `examples/`:** - -```console -cd scripts -python load_db.py \ ---username docker \ ---password password \ ---database pephub -../examples -``` - -**4. (_Optional_) GitHub Authentication Client Setup** - -_pephub_ uses GitHub for namespacing and authentication. As such, a GitHub application capable of logging in users is required. We've [included instructions](https://github.com/pepkit/pephub/blob/master/docs/authentication.md#setting-up-github-oauth-for-your-own-server) for setting this up locally using your own GitHub account. - -**5. (_Optional_) Vector Database Setup** - -We've added [semantic-search](https://huggingface.co/course/chapter5/6?fw=tf#using-embeddings-for-semantic-search) capabilities to pephub. Optionally, you may host an instance of the [qdrant](https://qdrant.tech/) **vector database** to store embeddings computed using a sentence transformer that has mined and processed any relevant metadata from PEPs. If no qdrant connection settings are supplied, pephub will default to SQL search. Read more [here](docs/semantic-search.md). To run qdrant locally, simply run the following: - -``` -docker pull qdrant/qdrant -docker run -p 6333:6333 \ - -v $(pwd)/qdrant_storage:/qdrant/storage \ - qdrant/qdrant -``` - -_Note: If you wish to run the development environment with a pubic database, curate your `.env` file as such._ From 72cf41f7a46dea5aae8270619da95aa9dbff98d8 Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Thu, 8 Feb 2024 22:01:50 +0100 Subject: [PATCH 07/10] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aae9b8b8..c691f6f7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    - PEPhub + PEPhub

    **PEPhub** is a biological metadata server that lets you view, store, and share your sample metadata in form of [PEPs](https://pep.databio.org/en/latest/). It has 3 components: 1) a _database_ where PEPs are stored; 2) an _API_ to programmatically read and write PEPs in the database; and 3) a web-based _user interface_ to view and manage these PEPs via a front-end. From a7f0e62d3cb7934eabc917dd0f2a0c2b99a209e4 Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Thu, 8 Feb 2024 22:10:25 +0100 Subject: [PATCH 08/10] added logo --- README.md | 2 + docs/imgs/pephub_logo_big.svg | 182 ++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 docs/imgs/pephub_logo_big.svg diff --git a/README.md b/README.md index c691f6f7..96e9fbcc 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@

    PEPhub + +

    **PEPhub** is a biological metadata server that lets you view, store, and share your sample metadata in form of [PEPs](https://pep.databio.org/en/latest/). It has 3 components: 1) a _database_ where PEPs are stored; 2) an _API_ to programmatically read and write PEPs in the database; and 3) a web-based _user interface_ to view and manage these PEPs via a front-end. diff --git a/docs/imgs/pephub_logo_big.svg b/docs/imgs/pephub_logo_big.svg new file mode 100644 index 00000000..6a91f979 --- /dev/null +++ b/docs/imgs/pephub_logo_big.svg @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + PEPhub + + + + + + + + + + + From 6773c8bd25133cd600a947a812621f1c885f541a Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Thu, 8 Feb 2024 22:17:06 +0100 Subject: [PATCH 09/10] updated version --- docs/changelog.md | 12 ++++++++++++ pephub/_version.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 25c6d78b..a240da77 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,18 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format. +## [0.11.6] - 02-08-2024 + +### Fixed + +- Docs and docs links +- Bug in handsontable +- Response errors in samples and views + +### Added + +- Namespace endpoint + ## [0.11.5] - 02-02-2024 ### Fixed diff --git a/pephub/_version.py b/pephub/_version.py index 91df9743..be379744 100644 --- a/pephub/_version.py +++ b/pephub/_version.py @@ -1 +1 @@ -__version__ = "0.11.5" +__version__ = "0.11.6" From 4a21aa847f73d03b37fbcdc93d81d53b7ae6e75c Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Thu, 8 Feb 2024 22:46:14 +0100 Subject: [PATCH 10/10] pr comments --- pephub/routers/api/v1/namespace.py | 14 +++++++++++++- requirements/requirements-all.txt | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pephub/routers/api/v1/namespace.py b/pephub/routers/api/v1/namespace.py index f1ee0d3d..8190ea7b 100644 --- a/pephub/routers/api/v1/namespace.py +++ b/pephub/routers/api/v1/namespace.py @@ -22,6 +22,7 @@ ProjectUniqueNameError, ProjectAlreadyInFavorites, ProjectNotInFavorites, + NamespaceNotFoundError, ) from pepdbagent.const import DEFAULT_LIMIT_INFO from pepdbagent.models import ( @@ -456,4 +457,15 @@ async def get_namespace_information( agent: PEPDatabaseAgent = Depends(get_db), namespace: Optional[str] = None, ): - return agent.namespace.stats(namespace=namespace) + try: + return agent.namespace.stats(namespace=namespace) + except NamespaceNotFoundError: + raise HTTPException( + status_code=404, + detail=f"Namespace '{namespace}' not found.", + ) + except Exception: + raise HTTPException( + status_code=500, + detail=f"Internal server error. Unexpected return value. Error: 500", + ) diff --git a/requirements/requirements-all.txt b/requirements/requirements-all.txt index 48ed2544..3aa6f01f 100644 --- a/requirements/requirements-all.txt +++ b/requirements/requirements-all.txt @@ -1,7 +1,7 @@ fastapi>=0.108.0 psycopg>=3.1.15 -# pepdbagent @ git+https://github.com/pepkit/pepdbagent.git@dev#egg=pepdbagent -pepdbagent>=0.7.3 +pepdbagent @ git+https://github.com/pepkit/pepdbagent.git@dev#egg=pepdbagent +# pepdbagent>=0.7.3 peppy>=0.40.1 eido>=0.2.2 jinja2>=3.1.2