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

Basic Name Search API Endpoint #91

Merged
merged 2 commits into from
Dec 1, 2023
Merged
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
24 changes: 24 additions & 0 deletions backend/src/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,30 @@ def get_all_entries():
log.error(e)


@app.get("/search-entries/{query:str}", response_model=list[ProteinEntry] | None)
def search_entries(query: str):
"""Gets a list of protein entries by a search string
Returns: list[ProteinEntry] if found | None if not found
"""
with Database() as db:
try:
entries_sql = db.execute_return(
"""SELECT name, length, mass FROM proteins
WHERE name ILIKE \'%{}%\'""".format(query)
)
log.warn("log test")
log.warn(entries_sql)

# if we got a result back
if entries_sql is not None:
return [
ProteinEntry(name=name, length=length, mass=mass)
for name, length, mass in entries_sql
]
except Exception as e:
log.error(e)


@app.get("/protein-entry/{protein_name:str}", response_model=ProteinEntry | None)
def get_protein_entry(protein_name: str):
"""Get a single protein entry by its id
Expand Down
1 change: 0 additions & 1 deletion frontend/src/openapi/models/EditBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ export type EditBody = {
newName: string;
newContent?: (string | null);
};

1 change: 0 additions & 1 deletion frontend/src/openapi/models/HTTPValidationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ import type { ValidationError } from './ValidationError';
export type HTTPValidationError = {
detail?: Array<ValidationError>;
};

1 change: 0 additions & 1 deletion frontend/src/openapi/models/ProteinEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ export type ProteinEntry = {
mass: number;
content?: (string | null);
};

1 change: 0 additions & 1 deletion frontend/src/openapi/models/UploadBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ export type UploadBody = {
content: string;
pdbFileBase64: string;
};

1 change: 0 additions & 1 deletion frontend/src/openapi/models/ValidationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ export type ValidationError = {
msg: string;
type: string;
};

51 changes: 37 additions & 14 deletions frontend/src/openapi/services/DefaultService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class DefaultService {
/**
* Get All Entries
* Gets all protein entries from the database
* Returns: list[ProteinEntry] if found | None if not found
* Returns: list[ProteinEntry] if found | None if not found
* @returns any Successful Response
* @throws ApiError
*/
Expand All @@ -27,17 +27,40 @@ export class DefaultService {
});
}

/**
* Search Entries
* Gets a list of protein entries by a search string
* Returns: list[ProteinEntry] if found | None if not found
* @param query
* @returns any Successful Response
* @throws ApiError
*/
public static searchEntries(
query: string,
): CancelablePromise<(Array<ProteinEntry> | null)> {
return __request(OpenAPI, {
method: 'GET',
url: '/search-entries/{query}',
path: {
'query': query,
},
errors: {
422: `Validation Error`,
},
});
}

/**
* Get Protein Entry
* Get a single protein entry by its id
* Returns: ProteinEntry if found | None if not found
* @param proteinName
* Returns: ProteinEntry if found | None if not found
* @param proteinName
* @returns any Successful Response
* @throws ApiError
*/
public static getProteinEntry(
proteinName: string,
): CancelablePromise<(ProteinEntry | null)> {
proteinName: string,
): CancelablePromise<(ProteinEntry | null)> {
return __request(OpenAPI, {
method: 'GET',
url: '/protein-entry/{protein_name}',
Expand All @@ -52,13 +75,13 @@ export class DefaultService {

/**
* Delete Protein Entry
* @param proteinName
* @param proteinName
* @returns any Successful Response
* @throws ApiError
*/
public static deleteProteinEntry(
proteinName: string,
): CancelablePromise<any> {
proteinName: string,
): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'DELETE',
url: '/protein-entry/{protein_name}',
Expand All @@ -73,13 +96,13 @@ export class DefaultService {

/**
* Upload Protein Entry
* @param requestBody
* @param requestBody
* @returns any Successful Response
* @throws ApiError
*/
public static uploadProteinEntry(
requestBody: UploadBody,
): CancelablePromise<(UploadError | null)> {
requestBody: UploadBody,
): CancelablePromise<(UploadError | null)> {
return __request(OpenAPI, {
method: 'POST',
url: '/protein-upload',
Expand All @@ -93,13 +116,13 @@ export class DefaultService {

/**
* Edit Protein Entry
* @param requestBody
* @param requestBody
* @returns any Successful Response
* @throws ApiError
*/
public static editProteinEntry(
requestBody: EditBody,
): CancelablePromise<(UploadError | null)> {
requestBody: EditBody,
): CancelablePromise<(UploadError | null)> {
return __request(OpenAPI, {
method: 'PUT',
url: '/protein-edit',
Expand Down
101 changes: 101 additions & 0 deletions frontend/src/routes/searchtest/[query]/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<!--THIS IS ONLY A TEST FILE, IT OUGHT TO BE DELETED!!!-->
<script lang="ts">
import { onMount } from "svelte";
import { goto } from "$app/navigation";
import { Backend } from "$lib/backend";
import type { ProteinEntry } from "$lib/backend";
import { humanReadableProteinName, numberWithCommas } from "$lib/format";
import {
Table,
TableBody,
TableBodyCell,
TableBodyRow,
TableHead,
TableHeadCell,
} from "flowbite-svelte";
import { Tabs, TabItem } from "flowbite-svelte";
import { Card, Button, Toggle } from "flowbite-svelte";

export let data;
// at some point, this should be change to request from the backend
let allEntries: ProteinEntry[] | null = null;
onMount(async () => {
console.log("Requesting", data.query, "info from backend");
// calls get_all_entries() from backend
// to generate this Backend object run `./run.sh gen_api` for newly created server functions
allEntries = await Backend.searchEntries(data.query);
console.log(allEntries);
});
</script>

<!-- akin to <head /> in html -->
<svelte:head>
<title>Home</title>
</svelte:head>

<section>
<Tabs style="underline" contentClass="bg-none p-5">
<TabItem open title="Table">
<Table>
<TableHead>
<TableHeadCell>Protein name</TableHeadCell>
<TableHeadCell>Length</TableHeadCell>
<TableHeadCell>Mass (Da)</TableHeadCell>
</TableHead>
<TableBody tableBodyClass="divide-y">
{#if allEntries}
{#each allEntries as entry}
<TableBodyRow
class="cursor-pointer hover:bg-gray-100"
on:click={() => {
goto(`/protein/${entry.name}`);
}}
>
<TableBodyCell
><span class="text-primary-700"
>{humanReadableProteinName(entry.name)}</span
></TableBodyCell
>
<TableBodyCell>{entry.length}</TableBodyCell>
<TableBodyCell>{numberWithCommas(entry.mass)}</TableBodyCell>
</TableBodyRow>
{/each}
{/if}
</TableBody>
</Table>
</TabItem>
<TabItem title="Gallery">
<div class="entries">
{#if allEntries}
{#each allEntries as entry}
<Card
class="hover:shadow-lg cursor-pointer"
title="Click to see {entry.name}"
on:click={() => goto(`/protein/${entry.name}`)}
>
<div class="name text-primary-700">
{humanReadableProteinName(entry.name)}
</div>
<div class="description">
Length: {entry.length}, Mass (Da): {numberWithCommas(
entry.mass
)}
</div>
</Card>
{/each}
{/if}
</div>
</TabItem>
</Tabs>
</section>

<style>
.entries {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.name {
font-size: 1.5em;
}
</style>
7 changes: 7 additions & 0 deletions frontend/src/routes/searchtest/[query]/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* This scrapes the data from the route
* ie. /protein/your_mom -> { proteinName: "your_mom" }
*/
export function load({ params }) {
return { query: params.query };
}