- 
                Notifications
    You must be signed in to change notification settings 
- Fork 0
basic kg API service setup w participant and biosample #1
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| from fastapi import Header, HTTPException | ||
|  | ||
|  | ||
| async def get_token_header(x_token: str = Header()): | ||
| if x_token != "test-token": | ||
| raise HTTPException(status_code=400, detail="X-Token header invalid") | ||
|  | ||
|  | ||
| async def get_query_token(token: str): | ||
| if token != "sooyoung": | ||
| raise HTTPException(status_code=400, detail="No Sooyoung token provided") | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| from fastapi import Depends, FastAPI | ||
|  | ||
| from dependencies import get_query_token, get_token_header | ||
| # from internal import admin | ||
| from routers import biosamples, participants | ||
|  | ||
| import uvicorn | ||
| from fastapi_sqlalchemy import DBSessionMiddleware, db | ||
| import os | ||
| from dotenv import load_dotenv | ||
|  | ||
| load_dotenv('.env') | ||
|  | ||
| app = FastAPI(dependencies=[Depends(get_query_token)]) | ||
|  | ||
|  | ||
| app.include_router(participants.router) | ||
| app.include_router(biosamples.router) | ||
| # app.include_router( | ||
| # admin.router, | ||
| # prefix="/admin", | ||
| # tags=["admin"], | ||
| # dependencies=[Depends(get_token_header)], | ||
| # responses={418: {"description": "I'm a teapot"}}, | ||
| # ) | ||
|  | ||
| # to avoid csrftokenError | ||
| app.add_middleware(DBSessionMiddleware, db_url=os.environ['DATABASE_URL']) | ||
|  | ||
| @app.get("/") | ||
| async def root(): | ||
| return {"message": "Knowledge Graph API"} | ||
|  | ||
|  | ||
| # To run locally | ||
| if __name__ == '__main__': | ||
| uvicorn.run(app, host='0.0.0.0', port=8000) | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Annotations(BaseModel): | ||
| name: str | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Assay(BaseModel): | ||
| name: str | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Atlas(BaseModel): | ||
| type: Spatial, Dimensional | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| from dandischema import DandiBaseModel | ||
|  | ||
|  | ||
| class BioSample(DandiBaseModel): | ||
| """Description of the sample that was studied""" | ||
|  | ||
| identifier: Identifier = Field(nskey="schema") | ||
| sampleType: SampleType = Field( | ||
| description="Identifier for the sample characteristics (e.g., from OBI, Encode).", | ||
| nskey="dandi", | ||
| ) | ||
| assayType: Optional[List[AssayType]] = Field( | ||
| None, description="Identifier for the assay(s) used (e.g., OBI).", nskey="dandi" | ||
| ) | ||
| anatomy: Optional[List[Anatomy]] = Field( | ||
| None, | ||
| description="Identifier for what organ the sample belongs " | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'Identifier for the organ from which the sample derives.' maybe? | ||
| "to. Use the most specific descriptor from sources such as UBERON.", | ||
| nskey="dandi", | ||
| ) | ||
|  | ||
| wasDerivedFrom: Optional[List["BioSample"]] = Field( | ||
| None, | ||
| description="Describes the hierarchy of sample derivation or aggregation.", | ||
| nskey="prov", | ||
| ) | ||
| wasAttributedTo: Optional[List[Participant]] = Field( | ||
| None, | ||
| description="Participant(s) or Subject(s) associated with this sample.", | ||
| nskey="prov", | ||
| ) | ||
| sameAs: Optional[List[Identifier]] = Field(None, nskey="schema") | ||
| hasMember: Optional[List[Identifier]] = Field(None, nskey="prov") | ||
|  | ||
| _ldmeta = { | ||
| "rdfs:subClassOf": ["schema:Thing", "prov:Entity"], | ||
| "rdfs:label": "Information about the biosample.", | ||
| "nskey": "dandi", | ||
| } | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Cell(BaseModel): | ||
| location: str | ||
| cellType: CellType | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class CellbyGene(BaseModel): | ||
| cell: Cell | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class CellType(BaseModel): | ||
| name: str | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Instrument(BaseModel): | ||
| name: str | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Location(BaseModel): | ||
| photo: Photo | ||
| coordinates: [str, str] | ||
| atlasMap: dict(Atlas) | ||
| atlas: Atlas | ||
| overlappingLabels: [str, str] | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| from dandischema import DandiBaseModel | ||
|  | ||
|  | ||
| class Participant(DandiBaseModel): | ||
| """Description about the Participant or Subject studied. | ||
| The Participant or Subject can be any individual or synthesized Agent. The | ||
| properties of the Participant or Subject refers to information at the timepoint | ||
| when the Participant or Subject engaged in the production of data being described. | ||
| """ | ||
|  | ||
| identifier: Identifier = Field(nskey="schema") | ||
| altName: Optional[List[Identifier]] = Field(None, nskey="dandi") | ||
|  | ||
| strain: Optional[StrainType] = Field( | ||
| None, | ||
| description="Identifier for the strain of the participant or subject.", | ||
| nskey="dandi", | ||
| ) | ||
| cellLine: Optional[Identifier] = Field( | ||
| None, | ||
| description="Cell line associated with the participant or subject.", | ||
| nskey="dandi", | ||
| ) | ||
| vendor: Optional[Organization] = Field(None, nskey="dandi") | ||
| age: Optional[PropertyValue] = Field( | ||
| None, | ||
| description="A representation of age using ISO 8601 duration. This " | ||
| "should include a valueReference if anything other than " | ||
| "date of birth is used.", | ||
| nskey="dandi", | ||
| rangeIncludes="schema:Duration", | ||
| ) | ||
|  | ||
| sex: Optional[SexType] = Field( | ||
| None, | ||
| description="Identifier for sex of the participant or subject if " | ||
| "available. (e.g. from OBI)", | ||
| nskey="dandi", | ||
| ) | ||
| genotype: Optional[Union[List[GenotypeInfo], Identifier]] = Field( | ||
| None, | ||
| description="Genotype descriptor of participant or subject if available", | ||
| nskey="dandi", | ||
| ) | ||
| species: Optional[SpeciesType] = Field( | ||
| None, | ||
| description="An identifier indicating the taxonomic classification of " | ||
| "the participant or subject.", | ||
| nskey="dandi", | ||
| ) | ||
| disorder: Optional[List[Disorder]] = Field( | ||
| None, | ||
| description="Any current diagnosed disease or disorder associated with " | ||
| "the participant or subject.", | ||
| nskey="dandi", | ||
| ) | ||
|  | ||
| relatedParticipant: Optional[List[RelatedParticipant]] = Field( | ||
| None, | ||
| description="Information about related participants or subjects in a " | ||
| "study or across studies.", | ||
| nskey="dandi", | ||
| ) | ||
| sameAs: Optional[List[Identifier]] = Field( | ||
| None, | ||
| description="An identifier to link participants or subjects across datasets.", | ||
| nskey="schema", | ||
| ) | ||
|  | ||
| _ldmeta = { | ||
| "rdfs:subClassOf": ["prov:Agent"], | ||
| "rdfs:label": "Information about the participant or subject.", | ||
| "nskey": "dandi", | ||
| } | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| id: https://bican.org/examples/participant | ||
| name: participant | ||
| prefixes: | ||
| linkml: https://w3id.org/linkml/ | ||
| imports: | ||
| - linkml:types | ||
| default_range: string | ||
|  | ||
| classes: | ||
| Participant: | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i had a chance to discus this with a few folks and there are couple of considerations that should be added to this. 
 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, some ages are measured from conception, some from birth -- some measured in days, some in weeks, some in years, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @patrick-lloyd-ray - we think date of birth should capture most scenarios but is a sensitive field for humans. in dandi we use gestational reference and birth reference as two reference frames, and we are using the duration format for ISO8601 to allow for any age representation. however age as a duration is also limited across species which have stages. also, we had to invent a format for age range (based on ISO8601), when precise age is not available. age is a complicated concept ;) | ||
| attributes: | ||
| identifier: | ||
| altName: | ||
| strain: | ||
| cellLine: | ||
| vendor: | ||
| age: | ||
| sex: | ||
| genotype: | ||
| species: | ||
| disorder: | ||
| relatedParticipant: | ||
| sameAs: | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Protocol(BaseModel): | ||
| name: str | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from pydantic import BaseModel | ||
|  | ||
|  | ||
| class Provenance(BaseModel): | ||
| name: str | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think 'characteristics' is too broad here -- better to have 'Identifier for the type of sample (e.g., from OBI, Encode).'