Skip to content

Commit bad5481

Browse files
v3.7.0
* feat: added token-based limiter. * feat: applied limiter to the needed routes. * feat: tests in place for the token based limiter. * feat: env token is added to the yml files. * feat: enhanced CDK depictions * fix: main cleanup * fix: detailed linting * fix: abbreviations usage * fix: docstrings for abbreviations * feat: detailed tests for 2D depictions enhanced * fix: tests and radical perception along with title * fix: test coverage * fix: extended tests better coverage * fix: abbreviation tests * fix: abbreviation tests * feat: enhanced 2D depictions based on CDK * feat: fix radicals CDK * fix: templates * fix: rendering of radical images * fix: rendering of radical images debug * fix: mounted the env instead of fetching a single value. (#686) * fix: mounted the env instead of fetching a single value. * fix: mounted env in the rest of the yml files. * feat: added env example. --------- Co-authored-by: Sagar <sriramkanakam87@gmail.com> Co-authored-by: Sri Ram Sagar Kanakam <90332705+sriramkanakam87@users.noreply.github.com>
1 parent e799d05 commit bad5481

Some content is hidden

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

57 files changed

+14904
-468
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Authentication token for rate limiting bypass
2+
CMS_INTERNAL_AUTH_TOKEN=

app/dependencies.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

app/limiter.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import os
2+
3+
from slowapi import Limiter, _rate_limit_exceeded_handler
4+
from slowapi.errors import RateLimitExceeded
5+
from slowapi.util import get_remote_address
6+
from starlette.requests import Request as StarletteRequest
7+
8+
INTERNAL_AUTH_TOKEN = os.getenv("CMS_INTERNAL_AUTH_TOKEN")
9+
10+
11+
def custom_rate_limit_key_func(request: StarletteRequest):
12+
"""
13+
Custom key function for rate limiting.
14+
- Authenticated requests get unique keys to effectively bypass rate limiting
15+
- Other requests are rate limited by IP address
16+
"""
17+
token = request.headers.get("x-internal-auth")
18+
19+
# Check for valid authentication token
20+
if token and INTERNAL_AUTH_TOKEN and token == INTERNAL_AUTH_TOKEN:
21+
# Return a unique key for each authenticated request
22+
# This effectively bypasses rate limiting since each request gets its own bucket
23+
return f"auth_bypass_{id(request)}"
24+
# For unauthenticated requests, use IP-based rate limiting
25+
return get_remote_address(request)
26+
27+
28+
limiter = Limiter(key_func=custom_rate_limit_key_func)
29+
rate_limit_exceeded_handler = _rate_limit_exceeded_handler
30+
RateLimitExceededExc = RateLimitExceeded

app/main.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
from __future__ import annotations
22

3+
4+
# Import limiter and related objects from the shared limiter module
5+
from app.limiter import limiter, rate_limit_exceeded_handler, RateLimitExceededExc
6+
37
import os
48
from fastapi import FastAPI
59
from fastapi import status
@@ -8,6 +12,7 @@
812
from fastapi_versioning import VersionedFastAPI
913
from prometheus_fastapi_instrumentator import Instrumentator
1014
from typing import Dict
15+
from slowapi.middleware import SlowAPIMiddleware
1116

1217
from .routers import chem
1318
from .routers import converters
@@ -84,6 +89,11 @@ def create_app_metadata() -> Dict:
8489
version=os.getenv("RELEASE_VERSION", "1.0"),
8590
)
8691

92+
# Add middleware AFTER VersionedFastAPI creation
93+
app.state.limiter = limiter
94+
app.add_exception_handler(RateLimitExceededExc, rate_limit_exceeded_handler)
95+
app.add_middleware(SlowAPIMiddleware)
96+
8797
Instrumentator().instrument(app).expose(app)
8898

8999
origins = ["*"]

app/modules/cdk_depict/__init__.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
"""CDK Enhancement Modules for Chemical Depiction.
2+
3+
This package provides advanced CDK-based functionality for molecular depiction:
4+
5+
Core Functionality:
6+
- Hydrogen Display: Control hydrogen atom visibility (minimal, explicit, stereo, smart)
7+
- CXSMILES: Extended SMILES parsing with highlighting and coordinates
8+
- Abbreviations: Chemical group and reagent abbreviation system
9+
- Dative Bonds: Coordinate bond perception and display
10+
- Multicenter Bonds: η-complex and π-bonding support
11+
12+
Advanced Features:
13+
- Annotations: Atom/bond numbering, mapping, CIP labels
14+
- Aromatic Display: Circle-in-ring (donut) representation
15+
- Style Presets: Color schemes for different backgrounds
16+
- Advanced Controls: Zoom, stroke ratio, SVG units, structure flipping
17+
- Reaction Arrows: Different arrow types for reactions
18+
19+
Specialized:
20+
- Radical Perception: Unpaired electron detection
21+
- MDL HILITE: Highlighting from MDL/SDF files
22+
"""
23+
24+
# Hydrogen Display
25+
from app.modules.cdk_depict.hydrogen_display import (
26+
set_hydrogen_display,
27+
setHydrogenDisplay,
28+
HydrogenDisplayType,
29+
)
30+
31+
# CXSMILES Parser
32+
from app.modules.cdk_depict.cxsmiles_parser import (
33+
extract_cxsmiles_highlighting,
34+
)
35+
36+
# Abbreviations
37+
from app.modules.cdk_depict.abbreviations import (
38+
ChemicalAbbreviations,
39+
AbbreviationMode,
40+
AbbreviationOptions,
41+
)
42+
43+
# Dative Bonds
44+
from app.modules.cdk_depict.dative_bonds import (
45+
DativeBondPerception,
46+
DativeBondMode,
47+
)
48+
49+
# Multicenter Bonds
50+
from app.modules.cdk_depict.multicenter_bonds import (
51+
MulticenterBonds,
52+
MulticenterStyle,
53+
)
54+
55+
# Annotations
56+
from app.modules.cdk_depict.annotations import (
57+
AnnotationSystem,
58+
AnnotationMode,
59+
MAPPING_COLORS,
60+
)
61+
62+
# Aromatic Display
63+
from app.modules.cdk_depict.aromatic_display import (
64+
AromaticDisplaySystem,
65+
)
66+
67+
# Style Presets
68+
from app.modules.cdk_depict.style_presets import (
69+
StylePresetSystem,
70+
StylePreset,
71+
StyleConfiguration,
72+
STYLE_CONFIGURATIONS,
73+
)
74+
75+
# Advanced Controls
76+
from app.modules.cdk_depict.advanced_controls import (
77+
AdvancedControls,
78+
SVGUnits,
79+
)
80+
81+
# Reaction Depiction
82+
from app.modules.cdk_depict.reaction_depiction import (
83+
ReactionArrowSystem,
84+
ReactionArrowType,
85+
ARROW_ABBREV_MAP,
86+
)
87+
88+
# Radical Perception
89+
from app.modules.cdk_depict.radical_perception import (
90+
RadicalPerception,
91+
)
92+
93+
# MDL HILITE
94+
from app.modules.cdk_depict.mdl_hilite import (
95+
MDLHiliteParser,
96+
)
97+
98+
99+
__all__ = [
100+
# Hydrogen Display
101+
"set_hydrogen_display",
102+
"setHydrogenDisplay",
103+
"HydrogenDisplayType",
104+
# CXSMILES
105+
"CXSMILESParser",
106+
"CXSMILESData",
107+
"CXSMILESError",
108+
"StereoGroupType",
109+
"extract_cxsmiles_highlighting",
110+
# Abbreviations
111+
"ChemicalAbbreviations",
112+
"AbbreviationMode",
113+
"AbbreviationOptions",
114+
# Dative Bonds
115+
"DativeBondPerception",
116+
"DativeBondMode",
117+
# Multicenter Bonds
118+
"MulticenterBonds",
119+
"MulticenterStyle",
120+
# Annotations
121+
"AnnotationSystem",
122+
"AnnotationMode",
123+
"MAPPING_COLORS",
124+
# Aromatic Display
125+
"AromaticDisplaySystem",
126+
# Style Presets
127+
"StylePresetSystem",
128+
"StylePreset",
129+
"StyleConfiguration",
130+
"STYLE_CONFIGURATIONS",
131+
# Advanced Controls
132+
"AdvancedControls",
133+
"SVGUnits",
134+
# Reaction Depiction
135+
"ReactionArrowSystem",
136+
"ReactionArrowType",
137+
"ARROW_ABBREV_MAP",
138+
# Radical Perception
139+
"RadicalPerception",
140+
# MDL HILITE
141+
"MDLHiliteParser",
142+
]

0 commit comments

Comments
 (0)