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

Inject reversed MetaEdges based on API list config #94

Merged
merged 6 commits into from
Sep 27, 2024
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
27 changes: 24 additions & 3 deletions .github/workflows/test_cov.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
on: ["push", "pull_request"]

name: Test Codecov
name: Test in workspace

jobs:

Expand All @@ -9,7 +9,24 @@ jobs:
runs-on: ubuntu-latest
steps:

- uses: actions/checkout@v1
- name: Get branch name
id: branch-name
uses: tj-actions/[email protected]

- name: Checkout to specific branch
uses: actions/checkout@v3
id: specific-checkout
continue-on-error: true
with:
repository: biothings/biothings_explorer
ref: ${{ steps.branch-name.outputs.current_branch }}

- name: Checkout to main if above failed
if: steps.specific-checkout.outcome == 'failure'
uses: actions/checkout@v3
with:
repository: biothings/biothings_explorer
ref: main

- name: Use Node.js 18.x
uses: actions/setup-node@v3
Expand All @@ -23,10 +40,14 @@ jobs:

- name: pnpm install, generate coverage report
run: |
pnpm run clone
pnpm run git checkout ${{ steps.branch-name.outputs.current_branch }}
pnpm i
pnpm run test-cov
pnpm --filter smartapi-kg test-cov

- name: Send coverage report to codecov for visualization
uses: codecov/codecov-action@v3
with:
working-directory: ./packages/@biothings-explorer/smartapi-kg
files: ./coverage/lcov.info
verbose: true
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"@babel/runtime": "^7.23.2",
"@commitlint/cli": "^17.8.1",
"@commitlint/config-conventional": "^11.0.0",
"@biothings-explorer/utils": "workspace:../utils",
"axios": "^0.21.4",
"camelcase": "^6.3.0",
"core-js": "^3.33.1",
Expand Down
81 changes: 71 additions & 10 deletions src/operations_builder/sync_operations_builder_with_reasoner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { PredicatesMetadata } from "../types";
import Debug from "debug";
const debug = Debug("bte:smartapi-kg:SyncOperationsBuilderWithReasoner");
import { SmartAPISpec } from "../parser/types";
import { biolink } from "@biothings-explorer/utils";

declare global {
var missingAPIs: SmartAPISpec[];
Expand Down Expand Up @@ -45,11 +46,12 @@ export default class SyncOperationsBuilderWithReasoner extends BaseOperationsBui
}
//predicates are store as OBJ:{SUBJ:[predicates]}
//parses each layer accordingly
let injectedOps = 0;
Object.keys(metadata.predicates).map(obj => {
Object.keys(metadata.predicates[obj]).map(sbj => {
if (Array.isArray(metadata.predicates[obj][sbj])) {
metadata.predicates[obj][sbj].map(pred => {
ops.push({
const op = {
association: {
input_type: this.removeBioLinkPrefix(sbj),
input_id: metadata?.nodes?.[sbj]?.id_prefixes,
Expand All @@ -64,11 +66,11 @@ export default class SyncOperationsBuilderWithReasoner extends BaseOperationsBui
typeof pred === "string" || !pred.qualifiers
? undefined
: Object.fromEntries(
pred.qualifiers.map((q: any) => [
this.removeBioLinkPrefix(q.qualifier_type_id),
q.applicable_values.map(this.removeBioLinkPrefix),
]),
),
pred.qualifiers.map((q: any) => [
this.removeBioLinkPrefix(q.qualifier_type_id),
q.applicable_values.map(this.removeBioLinkPrefix),
]),
),
"x-translator": metadata.association["x-translator"],
"x-trapi": metadata.association["x-trapi"],
},
Expand All @@ -84,11 +86,70 @@ export default class SyncOperationsBuilderWithReasoner extends BaseOperationsBui
inputSeparator: ",",
tags: [...metadata.tags, ...["bte-trapi"]],
},
});
};
ops.push(op);
if (
!this._options.apiList ||
!this._options.apiList.include.find(
api => api.id === metadata.association.smartapi.id,
)?.includeFlipped
) {
return;
}
// Add inverse metaEdge if includeFlipped is true
const inverse_op = {
...op,
association: {
...op.association,
input_type: this.removeBioLinkPrefix(obj),
input_id: metadata?.nodes?.[obj]?.id_prefixes,
output_type: this.removeBioLinkPrefix(sbj),
output_id: metadata?.nodes?.[sbj]?.id_prefixes,
predicate: biolink.reverse(
this.removeBioLinkPrefix(
typeof pred === "string" ? pred : pred.predicate,
),
),
qualifiers:
typeof pred === "string" || !pred.qualifiers
? undefined
: Object.fromEntries(
pred.qualifiers.map((q: any) => {
let newQualifierType: string = q.qualifier_type_id;
let newQualifier: string[] = q.applicable_values.map(
this.removeBioLinkPrefix,
);
if (newQualifierType.includes("predicate")) {
newQualifier = newQualifier.map(biolink.reverse);
}
if (newQualifierType.includes("subject")) {
newQualifierType = newQualifierType.replace(
"subject",
"object",
);
} else if (newQualifierType.includes("object")) {
newQualifierType = newQualifierType.replace(
"object",
"subject",
);
}

return [newQualifierType, newQualifier];
}),
),
},
};
if (inverse_op.association.predicate) {
ops.push(inverse_op);
injectedOps += 1;
}
});
}
});
});
if (injectedOps) {
debug(`Injected ${injectedOps} inverse operations for ${metadata.association.api_name}`);
}
if (!(typeof this._options.apiList === "undefined")) {
return ops.filter(op => {
const includeSmartAPI = this._options.apiList.include.find(
Expand Down Expand Up @@ -150,7 +211,7 @@ export default class SyncOperationsBuilderWithReasoner extends BaseOperationsBui

private fetch(): PredicatesMetadata[] {
if (this._options.predicates) {
return this._options.predicates;
return this._options.predicates;
}

const file = fs.readFileSync(this._predicates_file_path, "utf-8");
Expand All @@ -166,7 +227,7 @@ export default class SyncOperationsBuilderWithReasoner extends BaseOperationsBui
this._options.component,
this._options.apiList,
this._file_path,
this._options.smartapiSpecs
this._options.smartapiSpecs,
);
const nonTRAPIOps = this.loadOpsFromSpecs(specs);
const predicatesMetadata = this.fetch();
Expand All @@ -177,7 +238,7 @@ export default class SyncOperationsBuilderWithReasoner extends BaseOperationsBui
undefined,
undefined,
this._file_path,
this._options.smartapiSpecs
this._options.smartapiSpecs,
).filter(
spec =>
"info" in spec &&
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface apiListItem {
id?: string;
infores?: string;
name: string;
includeFlipped?: boolean; // Automatically generate flipped MetaEdges (TRAPI only)
}

export interface apiListObject {
Expand Down
10 changes: 9 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
"esModuleInterop": true,
"resolveJsonModule": true,
"strict": false,
"noImplicitAny": false
"noImplicitAny": false,
"paths": {
"@biothings-explorer/utils": ["../utils"],
}
},
"include": [
"./src/**/*",
Expand All @@ -23,5 +26,10 @@
"exclude": [
"node_modules",
"__tests__/"
],
"references": [
{
"path": "../utils"
}
]
}
Loading