Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
505c386
Adds allowReserved for curie path parameter
ctrl-schaff Oct 16, 2025
0418d49
Initial re-organization of endpoint views
ctrl-schaff Dec 3, 2025
9002582
Remove the unneeded openapi metadata endpoint
ctrl-schaff Dec 8, 2025
a843605
Combine the GET and POST class-based CURIE handler
ctrl-schaff Dec 8, 2025
04d5543
Cleanup the views package
ctrl-schaff Dec 8, 2025
c901d3c
Remove the sanic openapi extension
ctrl-schaff Dec 8, 2025
4303452
Remove unused import in transformed module
ctrl-schaff Dec 8, 2025
af1c9a9
Remove the api docstrings from curie and trapi endpoints
ctrl-schaff Dec 9, 2025
8af76a8
Add the swagger ui doc to the launcher
ctrl-schaff Dec 10, 2025
ba5cbf4
Flush out removal of all sanic-ext openapi usage
ctrl-schaff Dec 10, 2025
a2ddbb3
Add the swagger-ui frontend
ctrl-schaff Dec 15, 2025
c4c1d21
Update the .gitignore for node projects
ctrl-schaff Dec 15, 2025
42d7f33
Revert launcher to original state
ctrl-schaff Dec 15, 2025
8a977e5
Remove whitespace from docker-compose
ctrl-schaff Dec 15, 2025
8b7b1be
Add the package-lock for the swagger-ui frontend
ctrl-schaff Dec 15, 2025
4c30e35
Update the dockerfile for the frontend build stage
ctrl-schaff Dec 15, 2025
a022820
Move the frontend to within the application directory ...
ctrl-schaff Dec 15, 2025
4ec845c
Update dockerfile frontend pathing
ctrl-schaff Dec 15, 2025
6df733a
Move the static content loading up a directory
ctrl-schaff Dec 15, 2025
76cc88f
Temporarily disable Caddy
ctrl-schaff Dec 15, 2025
2e20947
Revert the dockerfile changes
ctrl-schaff Dec 15, 2025
f95cd09
Fix test imports
ctrl-schaff Dec 15, 2025
f44bf0b
Remove the metadata endpoint test
ctrl-schaff Dec 15, 2025
d375587
Setup the web-app to be separate from the python package
ctrl-schaff Jan 27, 2026
4f38246
Fix pathing for web-app
ctrl-schaff Jan 27, 2026
d774ac6
Decode the CURIE prior to the parse attempt
ctrl-schaff Jan 28, 2026
0301caa
Leverage the direct swagger-ui/dist files
ctrl-schaff Jan 30, 2026
c4e5c7a
Simplify our docker build stages for web-app
ctrl-schaff Jan 30, 2026
e0e4147
Add static file path routing for sanic
ctrl-schaff Jan 30, 2026
bad3775
Move the web-app internal to the package structure
ctrl-schaff Feb 2, 2026
e8319b7
Setup a separate file for package directories
ctrl-schaff Feb 2, 2026
7e59def
Add static routes and content for ui
ctrl-schaff Feb 2, 2026
c82bfcd
Change directory name so gitignore doesn't hide it
ctrl-schaff Feb 2, 2026
3461946
Add webapp to the pyproject package files
ctrl-schaff Feb 2, 2026
92c7dbf
Setup a src based project layout
ctrl-schaff Feb 2, 2026
bbace63
Correct webapp docker file path
ctrl-schaff Feb 2, 2026
e4bfce9
Revert layout change
ctrl-schaff Feb 2, 2026
cc6d70f
Fix licensing warning with pyproject.toml file
ctrl-schaff Feb 2, 2026
999077e
Attempted fix for path
ctrl-schaff Feb 2, 2026
69c449f
Merge branch 'bugfix-swagger-ui-path-parameter-serialization' of gith…
ctrl-schaff Feb 2, 2026
abd6c1c
Add the FaviconView to avoid error logs
ctrl-schaff Feb 2, 2026
b988c7e
Update dockerfile
ctrl-schaff Feb 3, 2026
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
144 changes: 144 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,147 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/


# Node configuration
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.*
!.env.example

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist
.output

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Sveltekit cache directory
.svelte-kit/

# vitepress build output
**/.vitepress/dist

# vitepress cache directory
**/.vitepress/cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# Firebase cache directory
.firebase/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Vite files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vite/
1 change: 0 additions & 1 deletion biothings_annotator/annotator/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import logging
from typing import Dict

from biothings_annotator.annotator.settings import SERVICE_PROVIDER_API_HOST
from biothings_annotator.annotator.utils import get_client

logger = logging.getLogger(__name__)
Expand Down
7 changes: 7 additions & 0 deletions biothings_annotator/annotator/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

import logging
import urllib.parse
from typing import Dict, List, Union

try:
Expand Down Expand Up @@ -93,8 +94,14 @@ def parse_curie(curie: str, return_type: bool = True, return_id: bool = True):
"""
return both type and if (as a tuple) or either based on the input curie
"""
try:
curie = urllib.parse.unquote(curie, encoding="utf-8", errors="strict")
except UnicodeError as unicode_err:
raise InvalidCurieError(curie) from unicode_err

if ":" not in curie:
raise InvalidCurieError(curie)

_prefix, _id = curie.split(":", 1)
_type = BIOLINK_PREFIX_to_BioThings.get(_prefix, {}).get("type", None)
if return_id:
Expand Down
107 changes: 102 additions & 5 deletions biothings_annotator/application/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,104 @@
from typing import Dict
import logging
import pathlib

APPLICATION_DIRECTORY = pathlib.Path(__file__).resolve().absolute().parent
CLI_DIRECTORY = APPLICATION_DIRECTORY.joinpath("cli")
CONFIGURATION_DIRECTORY = APPLICATION_DIRECTORY.joinpath("configuration")
MIDDLEWARE_DIRECTORY = APPLICATION_DIRECTORY.joinpath("middleware")
VIEWS_DIRECTORY = APPLICATION_DIRECTORY.joinpath("views")
from sanic import Sanic

from biothings_annotator.application.exceptions import build_exception_handers
from biothings_annotator.application.middleware import build_middleware
from biothings_annotator.application.static import build_static_routes, build_static_content
from biothings_annotator.application.views import build_routes


logging.basicConfig()
logger = logging.getLogger("sanic-application")
logger.setLevel(logging.DEBUG)


def build_application(configuration: Dict = None) -> Sanic:
"""
Generates and returns an instance of the sanic.app.Sanic application
for the web server

***BEGIN IMPORTANT***
This must be kept separate from the AnnotatorCLI class methods. If you attempt
to leverage this as a class method, when the worker manager attempts to spawn
a process to call the partially initialized factory method, it will attempt
to pickle the instances of the class itself. So unless we take the effort
to make the class instance pickleable, we keep this target here for the moment
***END IMPORTANT***

The sanic.web.Sanic application has the following constructor:
https://sanic.dev/api/sanic.app.html#getting-started
class Sanic(
name: str,
config: Optional[config_type] = None,
ctx: Optional[ctx_type] = None,
router: Optional[Router] = None,
signal_router: Optional[SignalRouter] = None,
error_handler: Optional[ErrorHandler] = None,
env_prefix: Optional[str] = SANIC_,
request_class: Optional[Type[Request]] = None,
strict_slashes: bool = False,
log_config: Optional[Dict[str, Any]] = None,
configure_logging: bool = True,
dumps: Optional[Callable[..., AnyStr]] = None,
loads: Optional[Callable[..., Any]] = None,
inspector: bool = False,
inspector_class: Optional[Type[Inspector]] = None,
certloader_class: Optional[Type[CertLoader]] = None
)

Loads the following additional aspects for the webserver:
> routes
> middleware
> exception handlers
"""
application_configuration = configuration["application"]["configuration"]
extension_configuration = configuration["application"]["extension"]

configuration_settings = {}
configuration_settings.update(application_configuration)
configuration_settings.update(extension_configuration["cors"])

application = Sanic(name="biothings-annotator")
application.update_config(configuration_settings)

application_routes = build_routes()
static_routes = build_static_routes()
for route in (*application_routes, *static_routes):
try:
application.add_route(**route)
except Exception as gen_exc:
logger.exception(gen_exc)
logger.error("Unable to add route %s", route)
raise gen_exc

static_content = build_static_content()
for static_entry in static_content:
try:
application.static(static_entry[0], static_entry[1])
except Exception as gen_exc:
logger.exception(gen_exc)
logger.error("Unable to add static content %s", static_entry)
raise gen_exc

application_middleware = build_middleware()
for middleware in application_middleware:
try:
application.register_middleware(**middleware)
except Exception as gen_exc:
logger.exception(gen_exc)
logger.error("Unable to add middleware %s", middleware)
raise gen_exc

exception_handlers = build_exception_handers()
for exception_handler in exception_handlers:
try:
application.error_handler.add(**exception_handler)
except Exception as gen_exc:
logger.exception(gen_exc)
logger.error("Unable to add exception handler %s", exception_handler)
raise gen_exc

return application
2 changes: 1 addition & 1 deletion biothings_annotator/application/cli/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from sanic.cli.arguments import Group
from sanic_routing import __version__ as __routing_version__

from biothings_annotator.application import CONFIGURATION_DIRECTORY
from biothings_annotator.application.structure import CONFIGURATION_DIRECTORY

logging.basicConfig()
logger = logging.getLogger("sanic-application")
Expand Down
2 changes: 1 addition & 1 deletion biothings_annotator/application/cli/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from sanic.worker.loader import AppLoader

from biothings_annotator.application.cli.arguments import build_annotator_argument_groups, load_configuration
from biothings_annotator.application.cli.target import build_application
from biothings_annotator.application import build_application

logging.basicConfig()
logger = logging.getLogger("sanic-application")
Expand Down
Loading
Loading