Skip to content

🐛 Generate API base URL by active product ⚠️ #7619

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

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
95a88d1
fix api-key creation response
giancarloromeo Apr 30, 2025
1575ff7
continue
giancarloromeo Apr 30, 2025
32f109e
fix api url
giancarloromeo Apr 30, 2025
8c6c2da
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo Apr 30, 2025
a1a5b2c
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 5, 2025
221b5c0
Merge remote-tracking branch 'upstream/master' into fix-api-base-url-…
giancarloromeo May 5, 2025
710159e
fix host
giancarloromeo May 5, 2025
0ca6baf
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 5, 2025
1e751ac
add test
giancarloromeo May 5, 2025
7dda096
fix host
giancarloromeo May 5, 2025
2f04ab3
fix expected api
giancarloromeo May 5, 2025
2131eb8
typehint
giancarloromeo May 5, 2025
de3ecf6
fix port
giancarloromeo May 5, 2025
4c89d78
fix helper
giancarloromeo May 5, 2025
30f59e0
typecheck
giancarloromeo May 5, 2025
67d23fa
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 5, 2025
26dd896
use generator
giancarloromeo May 5, 2025
ca6d976
move to common
giancarloromeo May 5, 2025
fcd1abb
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 5, 2025
eb24d6b
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 5, 2025
2dc9a92
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 6, 2025
e711dea
move to iterator
giancarloromeo May 6, 2025
90de65e
fix iter
giancarloromeo May 6, 2025
6744d71
make more robust
giancarloromeo May 6, 2025
e7c0234
add product_api_base_url param
giancarloromeo May 8, 2025
c8db246
add product_api_base_url param
giancarloromeo May 8, 2025
73e7fe1
add missing param
giancarloromeo May 8, 2025
becbde2
add param
giancarloromeo May 8, 2025
e3f341b
add product_api_base_url param
giancarloromeo May 8, 2025
3acbfc5
add param
giancarloromeo May 8, 2025
6879782
fix test
giancarloromeo May 8, 2025
0a0d705
add nullable field
giancarloromeo May 8, 2025
b7bbe70
fix tests
giancarloromeo May 8, 2025
b8b8cfd
fix examples
giancarloromeo May 8, 2025
55dafb2
fix
giancarloromeo May 8, 2025
ddf542e
fix
giancarloromeo May 8, 2025
8fe7c52
fix
giancarloromeo May 8, 2025
1aa57ed
fix tests
giancarloromeo May 9, 2025
08f32ab
fix test
giancarloromeo May 9, 2025
d620252
fix typecheck
giancarloromeo May 9, 2025
7c89663
typecheck
giancarloromeo May 9, 2025
b9d66b7
typecheck
giancarloromeo May 9, 2025
817f7d7
add metadata
giancarloromeo May 9, 2025
caaa89b
typecheck
giancarloromeo May 9, 2025
b9e1d73
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 9, 2025
6ec1239
Merge remote-tracking branch 'upstream/master' into fix-api-base-url-…
giancarloromeo May 9, 2025
0e89788
Merge branch 'fix-api-base-url-generation' of github.com:giancarlorom…
giancarloromeo May 9, 2025
10e459f
typecheck
giancarloromeo May 9, 2025
856e7fc
fix iter_origins
giancarloromeo May 9, 2025
2d64c6a
continue
giancarloromeo May 12, 2025
5927feb
Merge remote-tracking branch 'upstream/master' into fix-api-base-url-…
giancarloromeo May 12, 2025
1a0b1df
fix api_base_url generation
giancarloromeo May 12, 2025
b169c6e
add missing param
giancarloromeo May 12, 2025
2e6d2ea
update
giancarloromeo May 12, 2025
03bab7e
remove
giancarloromeo May 12, 2025
5b8c9f8
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 12, 2025
e33c8e2
fix test
giancarloromeo May 12, 2025
d35e22c
Merge remote-tracking branch 'upstream/master' into fix-api-base-url-…
giancarloromeo May 12, 2025
7699e7a
Merge branch 'fix-api-base-url-generation' of github.com:giancarlorom…
giancarloromeo May 12, 2025
40699c0
fix test
giancarloromeo May 12, 2025
20ec910
fix mock
giancarloromeo May 12, 2025
5c9e2c2
fix tests
giancarloromeo May 13, 2025
ee08426
fix test
giancarloromeo May 13, 2025
c97eed0
Merge remote-tracking branch 'upstream/master' into fix-api-base-url-…
giancarloromeo May 13, 2025
416492e
fix tests
giancarloromeo May 13, 2025
d525a27
fix int tests
giancarloromeo May 13, 2025
6cf6dd7
fix
giancarloromeo May 13, 2025
26a01e1
fix
giancarloromeo May 13, 2025
9f77907
fix
giancarloromeo May 13, 2025
b5fd47f
fix
giancarloromeo May 13, 2025
9cec281
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 13, 2025
20094cb
fix param
giancarloromeo May 13, 2025
6d14a2d
fix api_base_url
giancarloromeo May 13, 2025
33765d5
add missing field
giancarloromeo May 13, 2025
891685d
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 13, 2025
c64c8ae
add api_base_url
giancarloromeo May 13, 2025
ed65503
fix param
giancarloromeo May 13, 2025
a574100
typecheck
giancarloromeo May 13, 2025
e8174a2
deprecate env var
giancarloromeo May 13, 2025
e7081b9
update spec
giancarloromeo May 13, 2025
405a480
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 13, 2025
d8b63bd
Merge remote-tracking branch 'upstream/master' into fix-api-base-url-…
giancarloromeo May 14, 2025
d10f236
remove env
giancarloromeo May 14, 2025
b9f6c47
remove env
giancarloromeo May 14, 2025
26e1892
not nullable
giancarloromeo May 14, 2025
38d7853
remove assert
giancarloromeo May 14, 2025
fefd466
add var
giancarloromeo May 14, 2025
866bde0
mocks
giancarloromeo May 14, 2025
394f48e
nullable
giancarloromeo May 14, 2025
64ea381
add assert
giancarloromeo May 14, 2025
1dd8043
add test
giancarloromeo May 14, 2025
8a319e6
tests
giancarloromeo May 14, 2025
c2d9da2
nullable field
giancarloromeo May 14, 2025
fffb8f2
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 14, 2025
1c116ee
remove msg
giancarloromeo May 14, 2025
bf2d4d6
flip
giancarloromeo May 14, 2025
4f89dda
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 14, 2025
56c718b
update spec
giancarloromeo May 14, 2025
e739fe9
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 14, 2025
c4ac547
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 14, 2025
52088bf
Merge branch 'master' into fix-api-base-url-generation
giancarloromeo May 14, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
from ...login.decorators import login_required
from ...models import RequestContext
from ...security.decorators import permission_required
from ...utils_aiohttp import envelope_json_response
from ...utils import is_ip_address
from ...utils_aiohttp import envelope_json_response, iter_originating_hosts
from .. import _service
from ..models import ApiKey
from .rest_exceptions import handle_plugin_requests_exceptions
Expand All @@ -36,6 +37,16 @@ class ApiKeysPathParams(StrictRequestParameters):
api_key_id: IDStr


def _get_api_base_url(request: web.Request) -> str:
originating_host = next(iter_originating_hosts(request))
api_host = (
f"api.{originating_host}"
if not is_ip_address(originating_host)
else originating_host
)
return f"{request.url.with_host(api_host).with_port(None).with_path('')}"


@routes.post(f"/{API_VTAG}/auth/api-keys", name="create_api_key")
@login_required
@permission_required("user.apikey.*")
Expand All @@ -55,8 +66,8 @@ async def create_api_key(request: web.Request):
api_key = ApiKeyCreateResponse.model_validate(
{
**asdict(created_api_key),
"api_base_url": "http://localhost:8000",
} # TODO: https://github.com/ITISFoundation/osparc-simcore/issues/6340 # @pcrespov
"api_base_url": _get_api_base_url(request),
}
)

return envelope_json_response(api_key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from .._meta import API_VTAG
from ..constants import APP_PRODUCTS_KEY, RQ_PRODUCT_KEY
from ..utils_aiohttp import iter_originating_hosts
from .models import Product

_logger = logging.getLogger(__name__)
Expand All @@ -20,16 +21,9 @@ def _get_default_product_name(app: web.Application) -> str:

def _discover_product_by_hostname(request: web.Request) -> str | None:
products: OrderedDict[str, Product] = request.app[APP_PRODUCTS_KEY]
#
# SEE https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
# SEE https://doc.traefik.io/traefik/getting-started/faq/#what-are-the-forwarded-headers-when-proxying-http-requests
originating_hosts = [
request.headers.get("X-Forwarded-Host"),
request.host,
]
for product in products.values():
for host in originating_hosts:
if host and product.host_regex.search(host):
for host in iter_originating_hosts(request):
if product.host_regex.search(host):
product_name: str = product.name
return product_name
return None
Expand Down
15 changes: 15 additions & 0 deletions services/web/server/src/simcore_service_webserver/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import asyncio
import hashlib
import ipaddress
import logging
import os
import sys
Expand Down Expand Up @@ -173,3 +174,17 @@ def compose_support_error_msg(

def get_traceback_string(exception: BaseException) -> str:
return "".join(traceback.format_exception(exception))


# -----------------------------------------------
#
# NETWORK
#


def is_ip_address(host: str) -> bool:
try:
ipaddress.ip_address(host)
return True
except ValueError:
return False
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import io
import logging
from collections.abc import Callable
from collections.abc import Callable, Generator
from typing import Any, Generic, Literal, TypeAlias, TypeVar

from aiohttp import web
Expand Down Expand Up @@ -128,3 +128,15 @@ class NextPage(BaseModel, Generic[PageParameters]):
..., description="Code name to the front-end page. Ideally a PageStr"
)
parameters: PageParameters | None = None


def iter_originating_hosts(request) -> Generator[str, None, None]:
#
# SEE https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
# SEE https://doc.traefik.io/traefik/getting-started/faq/#what-are-the-forwarded-headers-when-proxying-http-requests
for host in (
request.headers.get("X-Forwarded-Host"),
request.url.host,
):
if host:
yield host
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,20 @@ async def test_create_api_key(
expected: HTTPStatus,
):
display_name = "foo"
resp = await client.post("/v0/auth/api-keys", json={"displayName": display_name})
resp = await client.post(
"/v0/auth/api-keys",
json={"displayName": display_name},
headers={"X-Forwarded-Host": "osparc.io"},
)

data, errors = await assert_status(resp, expected)

if not errors:
assert data["displayName"] == display_name
assert "apiKey" in data
assert "apiSecret" in data
assert "apiBaseUrl" in data
assert data["apiBaseUrl"] == "http://api.osparc.io/"

resp = await client.get("/v0/auth/api-keys")
data, _ = await assert_status(resp, expected)
Expand Down
Loading