Skip to content

Fix CORS preflight handling#17

Merged
shuchenliu merged 5 commits into
mainfrom
cors
May 17, 2026
Merged

Fix CORS preflight handling#17
shuchenliu merged 5 commits into
mainfrom
cors

Conversation

@shuchenliu
Copy link
Copy Markdown
Member

fix #13

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds explicit CORS support to NodeNormalization’s Tornado handlers so browser-based clients can successfully perform CORS preflight (OPTIONS) requests (fixes #13), and adds a targeted regression test suite.

Changes:

  • Introduces NodeNormalizationBaseHandler with CORS header handling + an options() implementation for preflight requests.
  • Updates API endpoint handlers to inherit from NodeNormalizationBaseHandler so CORS applies across endpoints.
  • Adds tests/test_cors.py and hardens NodeNormalizationAPINamespace.load_configuration() to tolerate missing CLI options (via getattr).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_cors.py New tests validating CORS headers on GET and OPTIONS (preflight).
src/nodenorm/handlers/base.py New shared handler implementing CORS headers + OPTIONS handling.
src/nodenorm/handlers/version.py Switches handler base class to include CORS behavior.
src/nodenorm/handlers/set_identifiers.py Switches handler base class to include CORS behavior.
src/nodenorm/handlers/semantic_types.py Switches handler base class to include CORS behavior.
src/nodenorm/handlers/normalized_nodes.py Switches handler base class to include CORS behavior.
src/nodenorm/handlers/health.py Switches handler base class to include CORS behavior.
src/nodenorm/handlers/conflations.py Switches handler base class to include CORS behavior.
src/nodenorm/handlers/curie_prefix.py Switches handler base class to include CORS behavior.
src/nodenorm/namespace.py Makes option overrides tolerant of missing conf/host/port attributes.
Comments suppressed due to low confidence (1)

src/nodenorm/handlers/curie_prefix.py:15

  • curie_prefix.py defines class SemanticTypeHandler and constructs a response under semantic_types, which conflicts with the module/endpoint intent (/get_curie_prefixes, name = "curie_prefixes"). Since this class was modified in this PR (base class swap), it’s a good opportunity to rename it (and its response variable/shape if needed) to avoid confusion and future misrouting when/if it gets wired into build_handlers().
class SemanticTypeHandler(NodeNormalizationBaseHandler):
    """
    Mirror implementation to the renci implementation found at
    https://nodenormalization-sri.renci.org/docs

    We intend to mirror the /get_curie_prefixes endpoint
    """

    name = "curie_prefixes"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/nodenorm/handlers/base.py Outdated
Comment on lines +12 to +24
def set_default_headers(self):
origin = self.request.headers.get("Origin")
if origin is None:
return

requested_headers = self.request.headers.get("Access-Control-Request-Headers")

self.set_header("Access-Control-Allow-Origin", origin)
self.set_header("Access-Control-Allow-Credentials", "true")
self.set_header("Access-Control-Allow-Methods", self.cors_methods)
self.set_header("Access-Control-Allow-Headers", requested_headers or "*")
self.set_header("Access-Control-Max-Age", self.cors_max_age)
self.set_header("Vary", "Origin")
Comment thread tests/test_cors.py Outdated
Comment on lines +1 to +21
import importlib.util
from pathlib import Path

import tornado.web
from tornado.testing import AsyncHTTPTestCase


ORIGIN = "https://translatorsri.github.io"
BASE_HANDLER_PATH = Path(__file__).parents[1] / "src" / "nodenorm" / "handlers" / "base.py"


def load_base_handler():
spec = importlib.util.spec_from_file_location("_nodenorm_base_handler_under_test", BASE_HANDLER_PATH)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module.NodeNormalizationBaseHandler


NodeNormalizationBaseHandler = load_base_handler()


Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/nodenorm/handlers/curie_prefix.py:11

  • In curie_prefix.py, the handler class is named SemanticTypeHandler, which duplicates the name used in semantic_types.py and doesn’t match the module/docstring intent of handling /get_curie_prefixes. This is confusing and makes it easy to import the wrong handler; renaming the class (and aligning the response payload/name to the curie-prefixes endpoint) would make the codebase clearer.
class SemanticTypeHandler(NodeNormalizationBaseHandler):
    """
    Mirror implementation to the renci implementation found at
    https://nodenormalization-sri.renci.org/docs

Comment on lines +21 to +23
self.set_header("Access-Control-Allow-Origin", self.cors_origin)
self.set_header("Access-Control-Allow-Credentials", self.cors_allow_credentials)
self.set_header("Access-Control-Allow-Methods", self.cors_methods)
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Comment thread src/nodenorm/handlers/curie_prefix.py Outdated
Comment on lines 4 to 8
from nodenorm.handlers.base import NodeNormalizationBaseHandler


class SemanticTypeHandler(BaseHandler):
class SemanticTypeHandler(NodeNormalizationBaseHandler):
"""
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

cors_methods = "GET, POST, HEAD, OPTIONS"
cors_max_age = "600"

def set_default_headers(self):
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

@shuchenliu shuchenliu merged commit fdef1fc into main May 17, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CORS headers not set on NodeNorm ES CI

2 participants