Skip to content

Commit 4a3fa12

Browse files
committed
Merge remote-tracking branch 'origin/main' into add-opentelemetry-support
2 parents 104af34 + b7f465c commit 4a3fa12

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+3099
-873
lines changed

.github/workflows/biothings_annotator_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: [ "3.9", "3.10", "3.11", "3.12" ]
15+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
1616
steps:
1717
- name: Checkout biothings_annotator source
1818
uses: actions/checkout@v3

.gitignore

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,151 @@ cython_debug/
158158
# and can be added to the global gitignore or merged into this file. For a more nuclear
159159
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
160160
#.idea/
161+
162+
163+
# Node configuration
164+
# Logs
165+
logs
166+
*.log
167+
npm-debug.log*
168+
yarn-debug.log*
169+
yarn-error.log*
170+
lerna-debug.log*
171+
172+
# Diagnostic reports (https://nodejs.org/api/report.html)
173+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
174+
175+
# Runtime data
176+
pids
177+
*.pid
178+
*.seed
179+
*.pid.lock
180+
181+
# Directory for instrumented libs generated by jscoverage/JSCover
182+
lib-cov
183+
184+
# Coverage directory used by tools like istanbul
185+
coverage
186+
*.lcov
187+
188+
# nyc test coverage
189+
.nyc_output
190+
191+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
192+
.grunt
193+
194+
# Bower dependency directory (https://bower.io/)
195+
bower_components
196+
197+
# node-waf configuration
198+
.lock-wscript
199+
200+
# Compiled binary addons (https://nodejs.org/api/addons.html)
201+
build/Release
202+
203+
# Dependency directories
204+
node_modules/
205+
jspm_packages/
206+
207+
# Snowpack dependency directory (https://snowpack.dev/)
208+
web_modules/
209+
210+
# TypeScript cache
211+
*.tsbuildinfo
212+
213+
# Optional npm cache directory
214+
.npm
215+
216+
# Optional eslint cache
217+
.eslintcache
218+
219+
# Optional stylelint cache
220+
.stylelintcache
221+
222+
# Optional REPL history
223+
.node_repl_history
224+
225+
# Output of 'npm pack'
226+
*.tgz
227+
228+
# Yarn Integrity file
229+
.yarn-integrity
230+
231+
# dotenv environment variable files
232+
.env
233+
.env.*
234+
!.env.example
235+
236+
# parcel-bundler cache (https://parceljs.org/)
237+
.cache
238+
.parcel-cache
239+
240+
# Next.js build output
241+
.next
242+
out
243+
244+
# Nuxt.js build / generate output
245+
.nuxt
246+
dist
247+
.output
248+
249+
# Gatsby files
250+
.cache/
251+
# Comment in the public line in if your project uses Gatsby and not Next.js
252+
# https://nextjs.org/blog/next-9-1#public-directory-support
253+
# public
254+
255+
# vuepress build output
256+
.vuepress/dist
257+
258+
# vuepress v2.x temp and cache directory
259+
.temp
260+
.cache
261+
262+
# Sveltekit cache directory
263+
.svelte-kit/
264+
265+
# vitepress build output
266+
**/.vitepress/dist
267+
268+
# vitepress cache directory
269+
**/.vitepress/cache
270+
271+
# Docusaurus cache and generated files
272+
.docusaurus
273+
274+
# Serverless directories
275+
.serverless/
276+
277+
# FuseBox cache
278+
.fusebox/
279+
280+
# DynamoDB Local files
281+
.dynamodb/
282+
283+
# Firebase cache directory
284+
.firebase/
285+
286+
# TernJS port file
287+
.tern-port
288+
289+
# Stores VSCode versions used for testing VSCode extensions
290+
.vscode-test
291+
292+
# yarn v3
293+
.pnp.*
294+
.yarn/*
295+
!.yarn/patches
296+
!.yarn/plugins
297+
!.yarn/releases
298+
!.yarn/sdks
299+
!.yarn/versions
300+
301+
# Vite files
302+
vite.config.js.timestamp-*
303+
vite.config.ts.timestamp-*
304+
.vite/
305+
306+
307+
# local webapp
308+
biothings_annotator/webapp/*.sqlite3

biothings_annotator/annotator/annotator.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ async def annotate_curie(
9494
node_type, _id = parse_curie(curie)
9595
if not node_type:
9696
raise InvalidCurieError(curie)
97+
9798
res = await self.query_biothings(node_type, [_id], fields=fields)
99+
98100
if not raw:
99101
res = await self.transform(res, node_type)
100-
# res = [self.transform(r) for r in res[_id]]
102+
101103
if res and include_extra:
102104
await self.append_extra_annotations(res)
103105

@@ -165,7 +167,7 @@ async def annotate_curie_list(
165167

166168
if include_extra:
167169
# currently, we only need to append extra annotations for chem nodes
168-
self.append_extra_annotations(node_d, node_id_subset=node_list_by_type.get("chem", []))
170+
await self.append_extra_annotations(node_d, node_id_subset=node_list_by_type.get("chem", []))
169171
return node_d
170172

171173
async def annotate_trapi(
@@ -215,14 +217,19 @@ async def annotate_trapi(
215217

216218
if include_extra:
217219
# currently, we only need to append extra annotations for chem nodes
218-
self.append_extra_annotations(_node_d, node_id_subset=node_list_by_type["chem"])
220+
await self.append_extra_annotations(_node_d, node_id_subset=node_list_by_type["chem"])
219221

220222
# place the annotation objects back to the original node_d as TRAPI attributes
221223
for node_id, res in _node_d.items():
222224
res = {
223225
"attribute_type_id": "biothings_annotations",
224226
"value": res,
225227
}
228+
229+
node_attributes = node_d[node_id].get("attributes", None)
230+
if node_attributes is None:
231+
node_d[node_id]["attributes"] = []
232+
226233
if append:
227234
# append annotations to existing "attributes" field
228235
node_d[node_id]["attributes"].append(res)

biothings_annotator/annotator/transformer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import logging
88
from typing import Dict
99

10-
from biothings_annotator.annotator.settings import SERVICE_PROVIDER_API_HOST
1110
from biothings_annotator.annotator.utils import get_client
1211

1312
logger = logging.getLogger(__name__)

biothings_annotator/annotator/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ def parse_curie(curie: str, return_type: bool = True, return_id: bool = True):
9595
"""
9696
if ":" not in curie:
9797
raise InvalidCurieError(curie)
98+
9899
_prefix, _id = curie.split(":", 1)
99100
_type = BIOLINK_PREFIX_to_BioThings.get(_prefix, {}).get("type", None)
100101
if return_id:
Lines changed: 101 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,103 @@
1+
from typing import Dict
2+
import logging
13
import pathlib
24

3-
APPLICATION_DIRECTORY = pathlib.Path(__file__).resolve().absolute().parent
4-
CLI_DIRECTORY = APPLICATION_DIRECTORY.joinpath("cli")
5-
CONFIGURATION_DIRECTORY = APPLICATION_DIRECTORY.joinpath("configuration")
6-
MIDDLEWARE_DIRECTORY = APPLICATION_DIRECTORY.joinpath("middleware")
7-
VIEWS_DIRECTORY = APPLICATION_DIRECTORY.joinpath("views")
5+
from sanic import Sanic
6+
7+
from biothings_annotator.application.exceptions import build_exception_handers
8+
from biothings_annotator.application.middleware import build_middleware
9+
from biothings_annotator.application.static import build_static_routes, build_static_content
10+
from biothings_annotator.application.views import build_routes
11+
12+
logging.basicConfig()
13+
logger = logging.getLogger("sanic-application")
14+
logger.setLevel(logging.DEBUG)
15+
16+
17+
def build_application(configuration: Dict = None) -> Sanic:
18+
"""
19+
Generates and returns an instance of the sanic.app.Sanic application
20+
for the web server
21+
22+
***BEGIN IMPORTANT***
23+
This must be kept separate from the AnnotatorCLI class methods. If you attempt
24+
to leverage this as a class method, when the worker manager attempts to spawn
25+
a process to call the partially initialized factory method, it will attempt
26+
to pickle the instances of the class itself. So unless we take the effort
27+
to make the class instance pickleable, we keep this target here for the moment
28+
***END IMPORTANT***
29+
30+
The sanic.web.Sanic application has the following constructor:
31+
https://sanic.dev/api/sanic.app.html#getting-started
32+
class Sanic(
33+
name: str,
34+
config: Optional[config_type] = None,
35+
ctx: Optional[ctx_type] = None,
36+
router: Optional[Router] = None,
37+
signal_router: Optional[SignalRouter] = None,
38+
error_handler: Optional[ErrorHandler] = None,
39+
env_prefix: Optional[str] = SANIC_,
40+
request_class: Optional[Type[Request]] = None,
41+
strict_slashes: bool = False,
42+
log_config: Optional[Dict[str, Any]] = None,
43+
configure_logging: bool = True,
44+
dumps: Optional[Callable[..., AnyStr]] = None,
45+
loads: Optional[Callable[..., Any]] = None,
46+
inspector: bool = False,
47+
inspector_class: Optional[Type[Inspector]] = None,
48+
certloader_class: Optional[Type[CertLoader]] = None
49+
)
50+
51+
Loads the following additional aspects for the webserver:
52+
> routes
53+
> middleware
54+
> exception handlers
55+
"""
56+
application_configuration = configuration["application"]["configuration"]
57+
extension_configuration = configuration["application"]["extension"]
58+
59+
configuration_settings = {}
60+
configuration_settings.update(application_configuration)
61+
configuration_settings.update(extension_configuration["cors"])
62+
63+
application = Sanic(name="biothings-annotator")
64+
application.update_config(configuration_settings)
65+
66+
application_routes = build_routes()
67+
static_routes = build_static_routes()
68+
for route in (*application_routes, *static_routes):
69+
try:
70+
application.add_route(**route)
71+
except Exception as gen_exc:
72+
logger.exception(gen_exc)
73+
logger.error("Unable to add route %s", route)
74+
raise gen_exc
75+
76+
static_content = build_static_content()
77+
for static_entry in static_content:
78+
try:
79+
application.static(static_entry[0], static_entry[1])
80+
except Exception as gen_exc:
81+
logger.exception(gen_exc)
82+
logger.error("Unable to add static content %s", static_entry)
83+
raise gen_exc
84+
85+
application_middleware = build_middleware()
86+
for middleware in application_middleware:
87+
try:
88+
application.register_middleware(**middleware)
89+
except Exception as gen_exc:
90+
logger.exception(gen_exc)
91+
logger.error("Unable to add middleware %s", middleware)
92+
raise gen_exc
93+
94+
exception_handlers = build_exception_handers()
95+
for exception_handler in exception_handlers:
96+
try:
97+
application.error_handler.add(**exception_handler)
98+
except Exception as gen_exc:
99+
logger.exception(gen_exc)
100+
logger.error("Unable to add exception handler %s", exception_handler)
101+
raise gen_exc
102+
103+
return application

biothings_annotator/application/cli/arguments.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from sanic.cli.arguments import Group
1313
from sanic_routing import __version__ as __routing_version__
1414

15-
from biothings_annotator.application import CONFIGURATION_DIRECTORY
15+
from biothings_annotator.application.structure import CONFIGURATION_DIRECTORY
1616

1717
logging.basicConfig()
1818
logger = logging.getLogger("sanic-application")

biothings_annotator/application/cli/interface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from sanic.worker.loader import AppLoader
2222

2323
from biothings_annotator.application.cli.arguments import build_annotator_argument_groups, load_configuration
24-
from biothings_annotator.application.cli.target import build_application
24+
from biothings_annotator.application import build_application
2525

2626
logging.basicConfig()
2727
logger = logging.getLogger("sanic-application")

0 commit comments

Comments
 (0)