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

Updated.Request-HTML #590

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

akshitbansal2005
Copy link

Use of Pytest: The code uses the pytest framework, which is a popular choice for writing and running tests in Python. It facilitates easy test case management and offers powerful features for parameterization and fixtures.

Fixtures: Two fixtures are defined (html_session and async_html_session) for setting up synchronous and asynchronous HTML sessions, respectively. They ensure the sessions are properly created and closed, maintaining clean resource management.

Parameterization: The tests are parameterized with a list of URLs. This allows the same test logic to be applied to multiple inputs, promoting DRY (Don't Repeat Yourself) principles and simplifying test case management.

Test Cases
Synchronous Test (test_pagination):

Functionality: Tests synchronous HTTP requests using the HTMLSession.
Assertions:
Checks if the HTML content is retrieved successfully.
Validates that the response status code is 200.
Asserts the presence of a <title> tag in the HTML.
Error Handling: Catches and logs request exceptions, providing informative feedback on failures.
Asynchronous Test (test_async_pagination):

Functionality: Tests asynchronous HTTP requests using the AsyncHTMLSession.
Assertions: Similar to the synchronous test, it verifies HTML retrieval, checks the status code, and ensures a <title> tag is present.
Error Handling: Implements exception handling for async requests, similar to the synchronous test.
Concurrent Asynchronous Test (test_async_run):

Functionality: Tests concurrent fetching of multiple URLs asynchronously.
Assertions:
Ensures the number of responses matches the number of URLs requested.
Checks that each response is of type HTMLResponse and has a status code of 200.
Validates that a <title> tag exists in the HTML content.
Error Handling: Catches exceptions during concurrent fetching, ensuring that all requests are logged and failures are reported.

Issues Identified
Redundant Session Creation:

The HTMLSession and AsyncHTMLSession are created multiple times across tests, which can lead to performance issues and unnecessary resource consumption.
Duplicated Code:

Paths and URLs are constructed multiple times, leading to code duplication and potential for errors if changes are needed.
Use of partial:

While partial is used correctly, it can lead to confusion in test definitions. A clearer method of passing parameters would enhance readability.
Hardcoded Values:

Specific values such as the expected length of classes or links are hardcoded in multiple tests. It can be useful to define constants for such values for easier maintenance.
No Cleanup After Tests:

Some tests that create browser instances (e.g., test_bare_js_eval and test_bare_js_async_eval) do not ensure the browser closes after tests, potentially leading to resource leaks.
Assertion Messages:

Assertions lack messages which can make debugging tests harder when they fail. Adding messages would improve clarity.
Ambiguous Test Function Names:

Test names should convey more about what is being tested. This improves readability and maintainability.
Unused Imports:

The import of Browser from pyppeteer is unnecessary if not used directly in the code.
Not Following PEP 8 Standards:

Some style inconsistencies (e.g., spaces around =, line length, and indentation) need to be corrected to adhere to PEP 8.
Issues Identified
Session Creation: The HTMLSession and AsyncHTMLSession are created multiple times, which can lead to inefficiencies.

Asynchronous Function Definitions: The use of _test as an inner function within a loop can cause unexpected behavior. This is because the variable url will have the last value in the loop at the time the function executes.

Assert Logic: The assertion using next(r.html) and await r.html.__anext__() assumes that the HTML content always has an iterable response. This may not hold true for all URLs, and should be validated.

Unused Event Loop Parameter: The event_loop parameter in test_async_pagination is unnecessary since pytest-asyncio manages the loop for async tests.

No Cleanup of Sessions: Sessions should be properly closed after tests to prevent resource leaks.

Lack of Assert Messages: Assertions should include messages to provide more context if a test fails.
 1.HTML Structure Issues:
Non-semantic tags: Using the <p> tag for wrapping elements like iframes and buttons isn’t ideal. It’s better to use <div> or other appropriate container elements for these non-paragraph elements.
Missing alt attribute: The image tag <img class="logo" src="{{ pathto('_static/requests-html-logo.png', 1) }}" /> is missing an alt attribute for accessibility.
Inconsistent indentation: The indentation of the code is inconsistent in some places, which can make it harder to read and maintain.
2. JavaScript Issues:
Inline JavaScript: Embedding JavaScript within HTML (such as in <script> tags) isn’t recommended for maintainability. External files are preferable, allowing for better separation of concerns.
Inefficient use of script tags: The Twitter widget script should be placed in an external JavaScript file or loaded in a cleaner way. The same applies to other embedded scripts.
3. CSS Issues:
Inline styles: Instead of embedding styles directly in the HTML with <style>, it’s better to move CSS into an external file to improve readability and reusability.
Hardcoded values: The width and height values for the Algolia autocomplete (width: 100%; height: 1.5em) are hardcoded. Using relative or responsive units such as vw, vh, or rem can make the layout more flexible.
4. Redundant iframe parameters:
The iframe tags have redundant attributes such as frameborder="0", allowtransparency="true", and scrolling="0". These are either obsolete or unnecessary in modern browsers. For example, frameborder is deprecated in HTML5 and should be replaced with CSS.
5. Performance considerations:
Loading external scripts asynchronously: The <script> tags for loading external libraries, such as the Twitter widget and Algolia search, should explicitly use the async attribute if they don’t depend on each other to speed up page load time.
Key Improvements:
Use of Relative Units: The document width is now specified with max-width, making it more flexible and responsive.
Removal of !important: The !important was removed where it wasn’t necessary, which allows for better cascading and future overrides in CSS.
More Readable Script: The tracking script remains efficient and lightweight, but cleaned up the variable declaration (avoiding unnecessary var _gauges = _gauges || [] repetition inside the script tag).
Issues and Improvements:
asyncio Compatibility:

In test_async_pagination, the method __anext__() is used on the r.html object, but it's not appropriate to check if HTML content is iterable using this method. Instead, you can check if the HTML content is properly parsed or contains expected elements.
Session Management:

Opening and closing an asynchronous session (AsyncHTMLSession()) within each test can be improved by using a fixture. This will help avoid redundant session creation and cleanup across tests.
Improved Assertion Messaging:

The current assertion messages, such as "Failed to retrieve HTML content for {url}", can be made more informative to provide better insights during test failures.
Test Parallelization:

If the tests are run in parallel, separate session instances should be created for each test, especially for async requests. Fixtures with the right scope will handle this.
Simplifying Async Test Logic:

The test_async_run logic can be simplified to make the test cleaner and more readable.
Issues Identified:
Deprecated Python 2 Support Comments:

The shebang #!/usr/bin/env python might cause confusion as Python 2 has been deprecated. It is safer to specify Python 3 explicitly.
Additionally, the encoding declaration # -*- coding: utf-8 -*- is unnecessary in Python 3 as UTF-8 is the default encoding.
Static Metadata in setup():

In modern setuptools, it is preferred to move package metadata to a setup.cfg or pyproject.toml file. This makes the setup.py script cleaner and helps support declarative configuration.
Potential Error with README.rst:

If README.rst is missing, this will cause an error. It would be better to add a check for the file’s existence.
Suboptimal Error Handling for rmtree():

The try-except block catching OSError for rmtree() is too generic. It would be better to handle this error more explicitly.
Usage of os.system():

The os.system() function is prone to issues with platform compatibility and security concerns. A better alternative is to use subprocess.run(), which provides more robust error handling and works better cross-platform.
Hardcoding of Package Version in git tag:

Hardcoding the version in the git tag command could lead to issues if the version string is updated but not reflected in the tag. It would be better to use the version dynamically from the setup() arguments.
Lack of Documentation for Custom Command:

While the UploadCommand class is well-written, the use of custom commands may confuse users without adequate documentation. It’s important to add comments explaining this functionality.
Code Analysis
1. Class Definitions
AsyncHTMLSession: Inherits from BaseSession. It allows for asynchronous operations while managing a pool of threads to execute HTTP requests in parallel. It integrates with the pyppeteer library for browser automation.
2. Initialization (__init__ method)
Parameters:

loop: Allows an existing asyncio event loop to be passed in, which is beneficial for integrating with other asynchronous codebases.
workers: Specifies the number of threads for executing async requests. If not provided, it defaults to five times the number of CPU cores, which is a reasonable approach for performance optimization in concurrent scenarios.
mock_browser: A boolean to specify whether to use a mocked browser user agent, defaulting to True.
Super Constructor: Calls the superclass constructor (BaseSession) to initialize the session correctly. This ensures that all properties from the base class are set up before adding async functionality.

ThreadPoolExecutor: Uses a ThreadPoolExecutor to handle the execution of blocking requests in a separate thread, which is crucial for non-blocking asynchronous programming.

3. Request Handling (request method)
Partial Function Application: Utilizes functools.partial to create a new function with fixed arguments from the super().request method. This allows it to run in a separate thread using the run_in_executor method.

Asynchronous Execution: By offloading the synchronous request handling to a thread pool, this method enables the main event loop to remain responsive while waiting for HTTP responses.

4. Closing the Session (close method)
Browser Closure: Checks if a browser instance exists and closes it asynchronously. This prevents resource leaks and ensures that all opened browser instances are properly terminated.

Awaiting Super Close: Ensures that the base class's close method is awaited, which is important for asynchronous context management.

5. Running Coroutines (run method)
Coroutine Management: Accepts multiple coroutines as arguments, wraps each in asyncio.ensure_future, and waits for them to complete. This allows for batch processing of asynchronous tasks and returning results in the order they were passed in.

Error Handling: The run method does not currently handle exceptions that may arise from the coroutines. Implementing a try-except block around the coroutine execution would improve robustness.
HTML Structure:

The HTML structure is well-organized with clear sections (<div>, <footer>, and <ul>) that improve readability.
Semantic HTML is used (e.g., <footer>, <ul>, <li>), which aids in SEO and accessibility.
Back to Top Links:

Multiple "Back to Top" links (<a id="back-to-top-1"> and <a id="back-to-top-2">) are provided, enhancing user experience by allowing easy navigation.
Ensure that the same section ID is used consistently (e.g., #python-network) to prevent confusion.
Sitemap Navigation:

The nested structure of the sitemap is clear, with tiered lists that logically categorize links.
Each category has a clear heading, aiding in navigation.
Consider adding title attributes to links for better context, especially for non-descriptive link text.
Community and Success Stories Sections:

Well-defined sections for community involvement and success stories enhance user engagement.
The use of sub-navigation (<ul class="subnav menu">) is effective for displaying related links.
Footer Links:

The footer links are concise and provide essential resources for users (help, diversity, bug submission).
Including a status indicator for the site enhances transparency.
Copyright Section:

The copyright section is clearly laid out and includes essential legal links.
The use of <small> is appropriate for copyright notices, keeping the main text hierarchy intact.
JavaScript Inclusion:

The use of jQuery for handling events and interactions is common, but the specific version (1.8.2) is quite outdated. Consider updating to a newer version for better performance and security.
The fallback for jQuery is a good practice for ensuring compatibility.
Conditional comments for IE should be evaluated; they may no longer be necessary depending on your target audience.
Accessibility Considerations:

Ensure that all links have meaningful text and consider using ARIA attributes for improved accessibility.
The structure could benefit from adding more descriptive text or tooltips to enhance usability for screen readers.
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.

1 participant