Skip to content
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

Use endpoint as default connection option (ADR-119) #590

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

surminus
Copy link

@surminus surminus commented Feb 20, 2025

This implements ADR-119[1], which specifies the client connection options to update requests to the endpoints implemented as part of ADR-042[2].

The endpoint may be one of the following:

a routing policy name (such as main)
a nonprod routing policy name (such as nonprod:sandbox)
a FQDN such as foo.example.com
The endpoint option is not valid with any of environment, restHost or realtimeHost, but we still intend to support the legacy options.

If the client has been configured to use any of these legacy options, then they should continue to work in the same way, using the same primary and fallback hostnames.

If the client has not been explicitly configured, then the hostnames will change to the new ably.net domain when the package is upgraded.

Notes on implementation

As per previous guidance, I have not updated tests to use the endpoint client option, but since the hostnames are changing, then the assertions and default environment must be updated (from sandbox to nonprod:sandbox).

I have not added any explicit tests for the endpoint client option, but I can do this if we think it's necessary, although using environment is essentially the same as using endpoint.

See related Go and Ruby PRs:

[1] https://ably.atlassian.net/wiki/spaces/ENG/pages/3428810778/ADR-119+ClientOptions+for+new+DNS+structure
[2] https://ably.atlassian.net/wiki/spaces/ENG/pages/1791754276/ADR-042+DNS+Restructure

Summary by CodeRabbit

  • New Features

    • Refined connection configuration now uses an “endpoint” parameter instead of the previous environment setting, ensuring that both primary and fallback hosts are selected more reliably.
    • Updated service endpoints mean production connections default to the new primary host while sandbox (non-production) environments use revised host URLs.
  • Bug Fixes

    • Adjusted tests to align with new host configurations, ensuring accurate assertions for both production and sandbox environments.
  • Refactor

    • Streamlined configuration and validation minimizes conflicting inputs and clarifies host selection, enhancing overall connectivity.

Copy link

coderabbitai bot commented Feb 20, 2025

Walkthrough

The pull request updates the host configuration logic. In ably/transport/defaults.py, the Defaults class now uses an endpoint attribute instead of environment and removes several legacy attributes. Two new static methods, get_hostname and get_fallback_hosts, determine host details based on the endpoint. The Options class in ably/types/options.py has been updated to enforce mutual exclusivity between endpoint and environment, replacing the latter with endpoint internally. Test files have been adjusted with updated host URLs and environment settings to match these changes.

Changes

File(s) Change Summary
ably/transport/defaults.py Removed fallback_hosts, rest_host, and realtime_host; replaced environment with endpoint (defaulting to 'main'); added static methods get_hostname and get_fallback_hosts to construct hosts based on endpoint.
ably/types/options.py Updated constructor to accept endpoint (with mutual exclusivity against environment); replaced environment property and internal variable with endpoint; adjusted host retrieval logic using the new endpoint.
test/ably/rest/restinit_test.py, test/ably/rest/restpaginatedresult_test.py, test/ably/rest/restrequest_test.py, test/ably/testapp.py Updated host URL assertions and mocked endpoints to reflect changes in production, sandbox, and fallback configurations, including new URL formats and environment strings.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Options
    participant Defaults
    Client->>Options: Instantiate with endpoint (or environment)
    Options->>Options: Check mutual exclusivity (raise error if both provided)
    Options->>Defaults: Call get_hostname(endpoint)
    Defaults-->>Options: Return primary hostname
    Options->>Defaults: Call get_fallback_hosts(endpoint)
    Defaults-->>Options: Return fallback hosts
    Options-->>Client: Return configured Options instance
Loading

Poem

I'm a bunny, hopping with glee,
New endpoints shine for all to see.
I nibble on bugs with whiskers twitch,
As fallback hosts appear without a glitch.
With every hop and joyful cheer,
CodeRabbit sings: "Update, my dear!"
(_/) 🥕 Happy coding!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot temporarily deployed to staging/pull/590/features February 20, 2025 16:16 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
ably/transport/defaults.py (2)

47-57: Refine hostname derivation logic
These conditionals cover typical cases (FQDN, localhost, nonprod, main), but consider additional validations for custom endpoints or IPv6 addresses (beyond a simple :: check).


60-69: Evaluate fallback logic for different endpoint patterns
The fallback domain logic is straightforward for nonprod: and main, but consider whether the same approach is needed for other future or custom endpoint patterns.

Also applies to: 72-76

test/ably/rest/restinit_test.py (2)

79-79: Fix Yoda conditions in assertions.

The assertions use Yoda conditions which are not recommended in Python. Let's make them more readable.

-        assert "main.realtime.ably.net" == host, "Unexpected host mismatch %s" % host
+        assert host == "main.realtime.ably.net", "Unexpected host mismatch %s" % host

-        assert "sandbox.realtime.ably-nonprod.net" == host, "Unexpected host mismatch %s" % host
+        assert host == "sandbox.realtime.ably-nonprod.net", "Unexpected host mismatch %s" % host

Also applies to: 84-84

🧰 Tools
🪛 Ruff (0.8.2)

79-79: Yoda condition detected

Rewrite as host == "main.realtime.ably.net"

(SIM300)


185-185: Fix line length and Yoda conditions in assertions.

The lines exceed the maximum line length of 115 characters and use Yoda conditions.

-        assert 'https://main.realtime.ably.net' == '{0}://{1}'.format(ably.http.preferred_scheme, ably.http.preferred_host)
+        expected_url = 'https://main.realtime.ably.net'
+        actual_url = '{0}://{1}'.format(ably.http.preferred_scheme, ably.http.preferred_host)
+        assert actual_url == expected_url

-        assert 'http://main.realtime.ably.net' == '{0}://{1}'.format(ably.http.preferred_scheme, ably.http.preferred_host)
+        expected_url = 'http://main.realtime.ably.net'
+        actual_url = '{0}://{1}'.format(ably.http.preferred_scheme, ably.http.preferred_host)
+        assert actual_url == expected_url

Also applies to: 191-191

🧰 Tools
🪛 Ruff (0.8.2)

185-185: Yoda condition detected

(SIM300)

🪛 GitHub Actions: Linting check

[error] 185-185: E501 line too long (123 > 115 characters)

ably/types/options.py (2)

12-13: Fix line length in constructor parameters.

The line exceeds the maximum line length of 115 characters.

-                 tls_port=0, use_binary_protocol=True, queue_messages=False, recover=False, endpoint=None,
-                 environment=None, http_open_timeout=None, http_request_timeout=None, realtime_request_timeout=None,
+                 tls_port=0, use_binary_protocol=True, queue_messages=False,
+                 recover=False, endpoint=None, environment=None,
+                 http_open_timeout=None, http_request_timeout=None,
+                 realtime_request_timeout=None,
🧰 Tools
🪛 GitHub Actions: Linting check

[error] 13-13: E501 line too long (116 > 115 characters)


286-290: Consider adding a docstring for the fallback hosts logic.

The fallback hosts logic has been updated to use endpoint-based configuration, but the logic could benefit from documentation explaining the behavior.

         fallback_hosts = self.fallback_hosts
         if fallback_hosts is None:
+            # If rest_host is explicitly set, don't use fallback hosts
+            # Otherwise, get fallback hosts based on the endpoint
             if self.rest_host:
                 fallback_hosts = []
             else:
                 fallback_hosts = Defaults.get_fallback_hosts(self.endpoint)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7bd2ca and 3146e69.

📒 Files selected for processing (6)
  • ably/transport/defaults.py (2 hunks)
  • ably/types/options.py (6 hunks)
  • test/ably/rest/restinit_test.py (4 hunks)
  • test/ably/rest/restpaginatedresult_test.py (3 hunks)
  • test/ably/rest/restrequest_test.py (1 hunks)
  • test/ably/testapp.py (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • test/ably/rest/restrequest_test.py
🧰 Additional context used
🪛 Ruff (0.8.2)
test/ably/rest/restinit_test.py

79-79: Yoda condition detected

Rewrite as host == "main.realtime.ably.net"

(SIM300)


84-84: Yoda condition detected

Rewrite as host == "sandbox.realtime.ably-nonprod.net"

(SIM300)


185-185: Yoda condition detected

(SIM300)


191-191: Yoda condition detected

(SIM300)

🪛 GitHub Actions: Linting check
test/ably/rest/restinit_test.py

[error] 185-185: E501 line too long (123 > 115 characters)


[error] 191-191: E501 line too long (122 > 115 characters)

ably/types/options.py

[error] 13-13: E501 line too long (116 > 115 characters)

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: check (3.13)
  • GitHub Check: check (3.12)
  • GitHub Check: check (3.11)
  • GitHub Check: check (3.10)
  • GitHub Check: check (3.9)
  • GitHub Check: check (3.8)
🔇 Additional comments (9)
ably/transport/defaults.py (1)

5-5: Set default endpoint to 'main'
This aligns with ADR-119.

test/ably/rest/restpaginatedresult_test.py (4)

34-34: Update base_url to new default domain
Replacing rest.ably.io with main.realtime.ably.net is consistent with the new endpoint approach.


47-48: Update Link header references
Ensures the HTTP link headers match the new domain.


58-58: Use new domain in PaginatedResult query
Matches the endpoint logic in defaults and test configurations.


62-62: Adopt the updated domain for channel queries
Keeps consistency with the rest of the codebase changes.

test/ably/testapp.py (3)

17-18: Adopt nonprod host defaults
Replaces sandbox host references to point to sandbox.realtime.ably-nonprod.net, aligning test configuration with ADR-119 changes.


20-20: Switch environment default to 'nonprod:sandbox'
Reflects the new host naming convention and test alignment.


25-25: Verify conditional logic for custom rest_host values
When rest_host is not within realtime.ably-nonprod.net, the test harness forces ports to 8080/8081. Confirm this remains valid for future endpoint expansions.

ably/types/options.py (1)

45-57: LGTM! Good implementation of endpoint configuration.

The implementation correctly:

  1. Enforces mutual exclusivity between endpoint and environment
  2. Migrates environment value to endpoint if environment is provided
  3. Sets default endpoint from Defaults class

@github-actions github-actions bot temporarily deployed to staging/pull/590/features February 20, 2025 16:28 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
test/ably/rest/restinit_test.py (1)

184-221: 🛠️ Refactor suggestion

Fix Yoda conditions and update environment to endpoint.

Update the test to use endpoint instead of environment and fix Yoda conditions.

-        assert 'https://main.realtime.ably.net' == '{0}://{1}'.format(
+        assert '{0}://{1}'.format(
             ably.http.preferred_scheme, ably.http.preferred_host
-        )
+        ) == 'https://main.realtime.ably.net'

-        assert 'http://main.realtime.ably.net' == '{0}://{1}'.format(
+        assert '{0}://{1}'.format(
             ably.http.preferred_scheme, ably.http.preferred_host
-        )
+        ) == 'http://main.realtime.ably.net'

-        ably = AblyRest(token='token', environment='custom')
+        ably = AblyRest(token='token', endpoint='custom')
🧰 Tools
🪛 Ruff (0.8.2)

185-187: Yoda condition detected

(SIM300)


194-196: Yoda condition detected

(SIM300)


207-207: Yoda condition detected

Rewrite as excinfo.value.status_code == 401

(SIM300)


208-208: Yoda condition detected

Rewrite as excinfo.value.code == 40103

(SIM300)


209-209: Yoda condition detected

(SIM300)


215-218: Use contextlib.suppress(AblyException) instead of try-except-pass

Replace with contextlib.suppress(AblyException)

(SIM105)

🧹 Nitpick comments (3)
ably/transport/defaults.py (1)

60-77: Consider adding docstring to document the fallback host pattern.

The method correctly implements the fallback host generation logic but would benefit from documentation explaining the pattern used for both production and non-production environments.

 @staticmethod
 def get_fallback_hosts(endpoint="main"):
+    """Generate a list of fallback hosts based on the endpoint.
+    
+    Args:
+        endpoint (str, optional): The endpoint to generate fallback hosts for. Defaults to "main".
+            Can be a routing policy name (e.g., "main"), a non-production routing policy name
+            (e.g., "nonprod:sandbox"), or a custom endpoint.
+    
+    Returns:
+        list[str]: A list of fallback hostnames following the pattern:
+            - For nonprod: <root>.{a-e}.fallback.ably-realtime-nonprod.com
+            - For others: <endpoint>.{a-e}.fallback.ably-realtime.com
+    """
ably/types/options.py (1)

173-174: Consider adding setter for endpoint property.

While the current implementation treats endpoint as read-only, consider adding a setter to allow runtime modifications, similar to other properties in the class.

 @property
 def endpoint(self):
     return self.__endpoint
+
+@endpoint.setter
+def endpoint(self, value):
+    self.__endpoint = value
+    self.__rest_hosts = self.__get_rest_hosts()
+    self.__realtime_hosts = self.__get_realtime_hosts()
test/ably/rest/restinit_test.py (1)

79-80: Fix Yoda condition.

Rewrite the condition to improve readability.

-        assert "main.realtime.ably.net" == host, "Unexpected host mismatch %s" % host
+        assert host == "main.realtime.ably.net", "Unexpected host mismatch %s" % host
🧰 Tools
🪛 Ruff (0.8.2)

79-79: Yoda condition detected

Rewrite as host == "main.realtime.ably.net"

(SIM300)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3146e69 and 3c1a33d.

📒 Files selected for processing (6)
  • ably/transport/defaults.py (2 hunks)
  • ably/types/options.py (6 hunks)
  • test/ably/rest/restinit_test.py (4 hunks)
  • test/ably/rest/restpaginatedresult_test.py (3 hunks)
  • test/ably/rest/restrequest_test.py (1 hunks)
  • test/ably/testapp.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/ably/rest/restpaginatedresult_test.py
  • test/ably/rest/restrequest_test.py
  • test/ably/testapp.py
🧰 Additional context used
🪛 Ruff (0.8.2)
test/ably/rest/restinit_test.py

79-79: Yoda condition detected

Rewrite as host == "main.realtime.ably.net"

(SIM300)


84-84: Yoda condition detected

Rewrite as host == "sandbox.realtime.ably-nonprod.net"

(SIM300)


185-187: Yoda condition detected

(SIM300)


194-196: Yoda condition detected

(SIM300)

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: check (3.13)
  • GitHub Check: check (3.12)
  • GitHub Check: check (3.11)
  • GitHub Check: check (3.10)
  • GitHub Check: check (3.9)
  • GitHub Check: check (3.8)
🔇 Additional comments (6)
ably/transport/defaults.py (2)

5-5: LGTM!

The default endpoint value 'main' aligns with ADR-119 specifications.


47-58: LGTM! Well-structured hostname resolution logic.

The get_hostname method correctly handles all endpoint formats specified in ADR-119:

  • Fully qualified domain names (contains ".")
  • IPv6 addresses (contains "::")
  • Localhost
  • Non-production routing policy (starts with "nonprod:")
  • Production routing policy ("main")
  • Custom routing policy (fallback case)
ably/types/options.py (4)

12-18: LGTM! Constructor signature updated correctly.

The endpoint parameter has been added while maintaining backward compatibility with environment.


46-58: LGTM! Robust validation and fallback logic.

The code correctly:

  • Prevents simultaneous use of endpoint and environment
  • Falls back to environment value if endpoint is not provided
  • Uses default endpoint from Defaults class as final fallback

277-291: LGTM! Host resolution logic updated correctly.

The code properly handles:

  • Custom rest_host override
  • Endpoint-based hostname resolution
  • Fallback host generation based on endpoint

307-308: LGTM! Realtime host resolution updated.

The code correctly uses the new endpoint-based hostname resolution for realtime hosts.

Comment on lines +82 to +84
ably = AblyRest(token='foo', environment="nonprod:sandbox")
host = ably.options.get_rest_host()
assert "sandbox-rest.ably.io" == host, "Unexpected host mismatch %s" % host
assert "sandbox.realtime.ably-nonprod.net" == host, "Unexpected host mismatch %s" % host
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix Yoda condition and update environment to endpoint.

Update the test to use endpoint instead of environment for consistency with ADR-119.

-        ably = AblyRest(token='foo', environment="nonprod:sandbox")
+        ably = AblyRest(token='foo', endpoint="nonprod:sandbox")
         host = ably.options.get_rest_host()
-        assert "sandbox.realtime.ably-nonprod.net" == host, "Unexpected host mismatch %s" % host
+        assert host == "sandbox.realtime.ably-nonprod.net", "Unexpected host mismatch %s" % host
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ably = AblyRest(token='foo', environment="nonprod:sandbox")
host = ably.options.get_rest_host()
assert "sandbox-rest.ably.io" == host, "Unexpected host mismatch %s" % host
assert "sandbox.realtime.ably-nonprod.net" == host, "Unexpected host mismatch %s" % host
ably = AblyRest(token='foo', endpoint="nonprod:sandbox")
host = ably.options.get_rest_host()
assert host == "sandbox.realtime.ably-nonprod.net", "Unexpected host mismatch %s" % host
🧰 Tools
🪛 Ruff (0.8.2)

84-84: Yoda condition detected

Rewrite as host == "sandbox.realtime.ably-nonprod.net"

(SIM300)

Comment on lines +106 to +112
ably = AblyRest(token='foo', environment='nonprod:sandbox', http_max_retry_count=10)
assert sorted(Defaults.get_fallback_hosts('nonprod:sandbox')) == sorted(
ably.options.get_fallback_rest_hosts())

# Fallback hosts and environment not specified (RSC15g3)
ably = AblyRest(token='foo', http_max_retry_count=10)
assert sorted(Defaults.fallback_hosts) == sorted(ably.options.get_fallback_rest_hosts())
assert sorted(Defaults.get_fallback_hosts()) == sorted(ably.options.get_fallback_rest_hosts())
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update environment to endpoint in fallback hosts test.

For consistency with ADR-119, update the test to use endpoint instead of environment.

-        ably = AblyRest(token='foo', environment='nonprod:sandbox', http_max_retry_count=10)
+        ably = AblyRest(token='foo', endpoint='nonprod:sandbox', http_max_retry_count=10)
         assert sorted(Defaults.get_fallback_hosts('nonprod:sandbox')) == sorted(
             ably.options.get_fallback_rest_hosts())
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ably = AblyRest(token='foo', environment='nonprod:sandbox', http_max_retry_count=10)
assert sorted(Defaults.get_fallback_hosts('nonprod:sandbox')) == sorted(
ably.options.get_fallback_rest_hosts())
# Fallback hosts and environment not specified (RSC15g3)
ably = AblyRest(token='foo', http_max_retry_count=10)
assert sorted(Defaults.fallback_hosts) == sorted(ably.options.get_fallback_rest_hosts())
assert sorted(Defaults.get_fallback_hosts()) == sorted(ably.options.get_fallback_rest_hosts())
ably = AblyRest(token='foo', endpoint='nonprod:sandbox', http_max_retry_count=10)
assert sorted(Defaults.get_fallback_hosts('nonprod:sandbox')) == sorted(
ably.options.get_fallback_rest_hosts())
# Fallback hosts and environment not specified (RSC15g3)
ably = AblyRest(token='foo', http_max_retry_count=10)
assert sorted(Defaults.get_fallback_hosts()) == sorted(ably.options.get_fallback_rest_hosts())

This implements ADR-119[1], which specifies the client connection
options to update requests to the endpoints implemented as part of
ADR-042[2].

The endpoint may be one of the following:

* a routing policy name (such as main)
* a nonprod routing policy name (such as nonprod:sandbox)
* a FQDN such as foo.example.com

The endpoint option is not valid with any of environment, restHost or
realtimeHost, but we still intend to support the legacy options.

If the client has been configured to use any of these legacy options,
then they should continue to work in the same way, using the same
primary and fallback hostnames.

If the client has not been explicitly configured, then the hostnames
will change to the new ably.net domain when the package is upgraded.

[1] https://ably.atlassian.net/wiki/spaces/ENG/pages/3428810778/ADR-119+ClientOptions+for+new+DNS+structure
[2] https://ably.atlassian.net/wiki/spaces/ENG/pages/1791754276/ADR-042+DNS+Restructure
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
ably/types/options.py (1)

176-177: Add endpoint property documentation.

Consider adding docstring to the endpoint property to describe its purpose and valid values.

 @property
 def endpoint(self):
+    """
+    The endpoint used for host resolution. Can be:
+    - A routing policy name (e.g., "main")
+    - A non-production routing policy (e.g., "nonprod:sandbox")
+    - A fully qualified domain name (e.g., "foo.example.com")
+    """
     return self.__endpoint
test/ably/rest/restinit_test.py (3)

79-79: Fix Yoda conditions in assertions.

Update the assertions to follow Python's conventional comparison order.

-        assert "main.realtime.ably.net" == host, "Unexpected host mismatch %s" % host
+        assert host == "main.realtime.ably.net", "Unexpected host mismatch %s" % host
-        assert "sandbox.realtime.ably-nonprod.net" == host, "Unexpected host mismatch %s" % host
+        assert host == "sandbox.realtime.ably-nonprod.net", "Unexpected host mismatch %s" % host

Also applies to: 84-84

🧰 Tools
🪛 Ruff (0.8.2)

79-79: Yoda condition detected

Rewrite as host == "main.realtime.ably.net"

(SIM300)


106-108: Update environment to endpoint in test.

For consistency with ADR-119, update the test to use endpoint instead of environment.

-        ably = AblyRest(token='foo', environment='nonprod:sandbox', http_max_retry_count=10)
+        ably = AblyRest(token='foo', endpoint='nonprod:sandbox', http_max_retry_count=10)
         assert sorted(Defaults.get_fallback_hosts('nonprod:sandbox')) == sorted(
             ably.options.get_fallback_rest_hosts())

185-187: Fix Yoda conditions in URL assertions.

Update the URL assertions to follow Python's conventional comparison order.

-        assert 'https://main.realtime.ably.net' == '{0}://{1}'.format(
+        assert '{0}://{1}'.format(
             ably.http.preferred_scheme, ably.http.preferred_host
-        )
+        ) == 'https://main.realtime.ably.net'

-        assert 'http://main.realtime.ably.net' == '{0}://{1}'.format(
+        assert '{0}://{1}'.format(
             ably.http.preferred_scheme, ably.http.preferred_host
-        )
+        ) == 'http://main.realtime.ably.net'

Also applies to: 194-196

🧰 Tools
🪛 Ruff (0.8.2)

185-187: Yoda condition detected

(SIM300)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c1a33d and d9706dd.

📒 Files selected for processing (6)
  • ably/transport/defaults.py (2 hunks)
  • ably/types/options.py (6 hunks)
  • test/ably/rest/restinit_test.py (4 hunks)
  • test/ably/rest/restpaginatedresult_test.py (3 hunks)
  • test/ably/rest/restrequest_test.py (1 hunks)
  • test/ably/testapp.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/ably/rest/restrequest_test.py
  • test/ably/rest/restpaginatedresult_test.py
  • test/ably/testapp.py
🧰 Additional context used
🪛 Ruff (0.8.2)
test/ably/rest/restinit_test.py

79-79: Yoda condition detected

Rewrite as host == "main.realtime.ably.net"

(SIM300)


84-84: Yoda condition detected

Rewrite as host == "sandbox.realtime.ably-nonprod.net"

(SIM300)


185-187: Yoda condition detected

(SIM300)


194-196: Yoda condition detected

(SIM300)

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: check (3.13)
  • GitHub Check: check (3.12)
  • GitHub Check: check (3.11)
  • GitHub Check: check (3.10)
  • GitHub Check: check (3.9)
  • GitHub Check: check (3.8)
🔇 Additional comments (7)
ably/transport/defaults.py (3)

5-5: LGTM! Endpoint configuration aligns with ADR-119.

The default endpoint is set to 'main', which is the correct default for production environments.


47-58: LGTM! Hostname resolution logic is well-structured.

The get_hostname method correctly handles all endpoint formats specified in ADR-119:

  • Fully qualified domain names (contains ".")
  • IPv6 addresses (contains "::")
  • Localhost
  • Non-production routing policy (starts with "nonprod:")
  • Production routing policy ("main")
  • Custom endpoints

60-77: LGTM! Fallback host generation is comprehensive.

The get_fallback_hosts method correctly generates fallback hosts based on the endpoint type:

  • Non-production endpoints use the ably-realtime-nonprod.com domain
  • Production endpoints use the ably-realtime.com domain
ably/types/options.py (4)

12-18: LGTM! Constructor parameters updated correctly.

The endpoint parameter has been added while maintaining backward compatibility with the environment parameter.


46-48: LGTM! Mutual exclusivity check added.

Correctly enforces mutual exclusivity between endpoint and environment parameters as specified in ADR-119.


53-61: LGTM! Environment to endpoint transition logic is correct.

The code properly handles the transition from environment to endpoint:

  1. Maps "production" environment to default endpoint
  2. Uses environment value as endpoint if endpoint is not specified
  3. Falls back to default endpoint if neither is specified

280-281: LGTM! Host resolution logic updated correctly.

The code properly uses the new endpoint-based host resolution while maintaining backward compatibility with rest_host.

Also applies to: 289-294

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant