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

chore: make posthog optional (use mock if not env not set) #249

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

nndn
Copy link

@nndn nndn commented Feb 10, 2025

Summary by CodeRabbit

  • New Features

    • Expanded analytics functionality now captures key user interactions—including conversations, signups, provider configurations, and data parsing—providing more accurate insights.
    • Improved application lifecycle management delivers enhanced reliability and smoother operational performance.
    • Centralized event tracking replaces legacy methods to streamline monitoring and reporting across the platform.
  • Bug Fixes

    • Enhanced error handling and logging for analytics events to ensure robustness during event capturing.
  • Chores

    • Removed legacy PostHogClient to simplify the codebase and improve maintainability.

Copy link
Contributor

coderabbitai bot commented Feb 10, 2025

Walkthrough

The changes integrate an AnalyticsService into the application by updating multiple API endpoints, controllers, and service classes. Method signatures have been updated to include analytics service dependency injection, replacing direct PostHogClient calls with calls to analytics_service.capture_event. Additionally, new lifecycle and dependency management functions have been added to initialize and access the analytics service. Overall, this refactoring centralizes event tracking across conversation, parsing, authentication, provider management, and secret management workflows.

Changes

Files Change Summary
app/api/router.py; app/modules/auth/auth_router.py; app/modules/conversations/conversations_router.py; app/modules/intelligence/provider/provider_router.py Added analytics_service dependency injection to API endpoints; updated method signatures to include analytics_service and replaced direct event calls with analytics_service.capture_event.
app/celery/tasks/parsing_tasks.py; app/modules/parsing/graph_construction/parsing_router.py; app/modules/parsing/graph_construction/parsing_controller.py; app/modules/parsing/graph_construction/parsing_service.py Integrated analytics_service into parsing tasks and controllers; updated method signatures and event names for consistent analytics tracking.
app/modules/conversations/conversation/conversation_controller.py; app/modules/conversations/conversation/conversation_service.py Injected analytics_service into conversation controller and service constructors; replaced PostHogClient event calls with analytics_service.capture_event in conversation operations.
app/core/dependencies.py; app/main.py Introduced new dependency functions and a lifespan context manager to initialize and manage the AnalyticsService during the application lifecycle.
app/modules/key_management/secret_manager.py Updated secret management methods by replacing direct PostHogClient calls with analytics_service dependency injection for event tracking in secret creation, deletion, and API key management.
app/modules/utils/analytics_service.py Added a new AnalyticsService interface along with MockAnalyticsService and PosthogAnalyticsService implementations, centralizing the analytics event capture mechanism.
app/modules/utils/posthog_helper.py Removed the PostHogClient file, as its functionality has been replaced by the new AnalyticsService implementations.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API
    participant Controller
    participant AnalyticsService
    Client->>API: Request (e.g., create conversation)
    API->>Controller: Call with analytics_service injected
    Controller->>AnalyticsService: capture_event("event_name", properties)
    Controller-->>API: Return response
    API-->>Client: Response with analytics integrated
Loading

Possibly related PRs

Poem

I hopped through lines of code with glee,
Injecting analytics so seamlessly.
Endpoints and controllers now sing in tune,
Tracking events like a bright full moon.
My rabbit heart leaps at each new line—
CodeRabbit’s joy in every design! 🐇
Happy hopping through analytics divine!


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ebedbad and 4587a50.

📒 Files selected for processing (1)
  • app/celery/tasks/parsing_tasks.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/celery/tasks/parsing_tasks.py

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.

Copy link
Contributor

@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: 3

🧹 Nitpick comments (8)
app/core/dependencies.py (2)

15-17: Remove unnecessary empty lines.

There are unnecessary empty lines between the comment and the function definition.

Apply this diff to improve readability:

# Analytics service configuration
-

def init_analytics_service() -> AnalyticsService:

19-20: Improve environment variable handling.

The current implementation uses empty string as default which requires an additional check. Consider using None as default to simplify the logic.

Apply this diff to improve the code:

-    POSTHOG_API_KEY = os.getenv("POSTHOG_API_KEY") or ""
-    POSTHOG_HOST = os.getenv("POSTHOG_HOST") or ""
+    POSTHOG_API_KEY = os.getenv("POSTHOG_API_KEY")
+    POSTHOG_HOST = os.getenv("POSTHOG_HOST")

-    if POSTHOG_API_KEY != "" and POSTHOG_HOST != "":
+    if POSTHOG_API_KEY and POSTHOG_HOST:
app/modules/utils/analytics_service.py (2)

2-2: Remove unused import.

The os module is imported but never used.

Apply this diff to remove the unused import:

-import os
🧰 Tools
🪛 Ruff (0.8.2)

2-2: os imported but unused

Remove unused import: os

(F401)


43-48: Enhance error handling in PosthogAnalyticsService.

The current error handling catches all exceptions and only logs a warning. Consider:

  1. Logging the event details that failed.
  2. Using a more specific exception type.

Apply this diff to improve error handling:

     def capture_event(self, user_id: str, event_name: str, properties: dict):
         try:
             self.posthog.capture(user_id, event=event_name, properties=properties)
-        except Exception as e:
-            logger.warning(f"Failed to send event: {e}")
+        except (ConnectionError, TimeoutError) as e:
+            logger.warning(
+                f"Failed to send event: {event_name} for user: {user_id} "
+                f"with properties: {properties}. Error: {e}"
+            )
app/modules/auth/auth_router.py (1)

80-88: Simplify the uid string formatting.

The f-string formatting is unnecessary since uid is already a string.

-                f"{uid}",
+                uid,
app/modules/conversations/conversations_router.py (1)

40-174: Refactor dependency injection to avoid function calls in argument defaults.

The current implementation triggers B008 warnings for using Depends function calls in argument defaults. While this works, it's recommended to perform the function calls within the function body.

Apply this pattern to refactor the dependency injection:

@staticmethod
@router.post("/conversations/", response_model=CreateConversationResponse)
async def create_conversation(
    conversation: CreateConversationRequest,
    db: Session,
    analytics_service: AnalyticsService,
    user: dict,
):
    """
    Example refactored method showing the pattern to apply to all methods.
    Dependencies are injected in the function body.
    """
    db = Depends(get_db)()
    analytics_service = Depends(get_analytics_service)()
    user = Depends(AuthService.check_auth)()
    
    user_id = user["user_id"]
    user_email = user["email"]
    controller = ConversationController(db, user_id, user_email, analytics_service)
    return await controller.create_conversation(conversation)
🧰 Tools
🪛 Ruff (0.8.2)

40-40: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


41-41: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


55-55: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


56-56: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


57-57: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


73-73: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


74-74: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


75-75: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


88-88: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


89-89: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


90-90: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


122-122: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


123-123: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


124-124: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


145-145: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


146-146: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


147-147: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


158-158: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


159-159: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


160-160: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


172-172: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


173-173: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


174-174: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/modules/key_management/secret_manager.py (1)

66-66: Address B008 warnings for FastAPI dependency injection.

The use of Depends() in parameter defaults is discouraged as it can lead to unexpected behavior. Instead, declare dependencies at the router level or move them inside the function.

Consider refactoring the dependency injection pattern:

-def create_secret(
-    request: CreateSecretRequest,
-    user=Depends(AuthService.check_auth),
-    analytics_service: AnalyticsService = Depends(get_analytics_service),
-    db: Session = Depends(get_db),
-):
+def create_secret(
+    request: CreateSecretRequest,
+    user: dict,
+    analytics_service: AnalyticsService,
+    db: Session,
+):

And declare dependencies at the router level:

@router.post("/secrets")
async def create_secret_endpoint(
    request: CreateSecretRequest,
    user: dict = Depends(AuthService.check_auth),
    analytics_service: AnalyticsService = Depends(get_analytics_service),
    db: Session = Depends(get_db),
):
    return SecretManager.create_secret(request, user, analytics_service, db)

Also applies to: 189-189, 261-261, 282-282

🧰 Tools
🪛 Ruff (0.8.2)

66-66: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/modules/conversations/conversation/conversation_service.py (1)

151-157: Improve code formatting for better readability.

The conditional check could be formatted more consistently.

Consider this formatting:

-        if (
-            state["agent_id"] in agent_list
-            and agent_list[state["agent_id"]] != "SYSTEM"
-        ):
+        if state["agent_id"] in agent_list and agent_list[state["agent_id"]] != "SYSTEM":
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b0e1086 and ebedbad.

📒 Files selected for processing (16)
  • app/api/router.py (4 hunks)
  • app/celery/tasks/parsing_tasks.py (2 hunks)
  • app/core/dependencies.py (1 hunks)
  • app/main.py (2 hunks)
  • app/modules/auth/auth_router.py (3 hunks)
  • app/modules/conversations/conversation/conversation_controller.py (1 hunks)
  • app/modules/conversations/conversation/conversation_service.py (12 hunks)
  • app/modules/conversations/conversations_router.py (9 hunks)
  • app/modules/intelligence/provider/provider_router.py (2 hunks)
  • app/modules/intelligence/provider/provider_service.py (1 hunks)
  • app/modules/key_management/secret_manager.py (9 hunks)
  • app/modules/parsing/graph_construction/parsing_controller.py (9 hunks)
  • app/modules/parsing/graph_construction/parsing_router.py (2 hunks)
  • app/modules/parsing/graph_construction/parsing_service.py (4 hunks)
  • app/modules/utils/analytics_service.py (1 hunks)
  • app/modules/utils/posthog_helper.py (0 hunks)
💤 Files with no reviewable changes (1)
  • app/modules/utils/posthog_helper.py
🧰 Additional context used
🪛 Ruff (0.8.2)
app/main.py

35-35: app.core.dependencies.init_analytics_service imported but unused

Remove unused import: app.core.dependencies.init_analytics_service

(F401)

app/modules/intelligence/provider/provider_router.py

32-32: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


33-33: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/modules/parsing/graph_construction/parsing_router.py

19-19: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/modules/auth/auth_router.py

46-46: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


47-47: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/api/router.py

59-59: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


79-79: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


80-80: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


81-81: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


102-102: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


103-103: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/modules/utils/analytics_service.py

2-2: os imported but unused

Remove unused import: os

(F401)

app/modules/key_management/secret_manager.py

66-66: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


189-189: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


261-261: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


262-262: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


282-282: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/modules/conversations/conversations_router.py

40-40: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


41-41: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


56-56: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


57-57: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


74-74: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


75-75: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


88-88: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


123-123: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


124-124: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


146-146: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


147-147: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


158-158: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


159-159: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


160-160: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


173-173: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


174-174: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

🔇 Additional comments (18)
app/modules/intelligence/provider/provider_router.py (2)

11-11: LGTM!

Clean import of analytics service dependencies.


29-41: LGTM!

Good integration of analytics service to track provider changes. The event is captured after successful provider change and includes relevant provider information.

🧰 Tools
🪛 Ruff (0.8.2)

31-31: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


32-32: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


33-33: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

app/modules/auth/auth_router.py (1)

17-17: LGTM!

Clean import of analytics service dependencies.

app/api/router.py (2)

23-23: LGTM!

Clean import of analytics service dependencies.


72-73: LGTM!

Good integration of analytics service across conversation and parsing endpoints. The service is properly passed to respective controllers.

Also applies to: 83-85, 110-112

app/modules/conversations/conversation/conversation_controller.py (2)

24-24: LGTM!

Clean import of analytics service dependencies.


28-41: LGTM!

Good integration of analytics service in the controller. The service is properly stored and passed to the conversation service.

app/main.py (1)

42-46: LGTM!

The lifespan context manager is correctly implemented using asynccontextmanager to initialize app state.

app/modules/conversations/conversations_router.py (1)

29-29: LGTM!

The import of AnalyticsService and get_analytics_service is correctly added.

app/modules/parsing/graph_construction/parsing_controller.py (2)

168-176: LGTM!

The analytics event capture is correctly implemented with consistent event name and payload structure.


237-245: LGTM!

The analytics event capture is correctly implemented with consistent event name and payload structure.

app/modules/intelligence/provider/provider_service.py (1)

80-80: LGTM!

The return value enhancement improves the API response by including the provider name.

app/modules/key_management/secret_manager.py (1)

99-103: LGTM! Analytics integration looks good.

The analytics service integration is consistent across all operations, capturing relevant events with appropriate metadata.

Also applies to: 209-213, 249-253, 267-274, 292-294

app/modules/parsing/graph_construction/parsing_service.py (2)

36-37: LGTM! Constructor changes look good.

The analytics service is properly injected through the constructor and stored as an instance variable.

Also applies to: 43-43


189-193: LGTM! Analytics integration is consistent.

The analytics service is used appropriately to track project status events with relevant metadata.

Also applies to: 205-209, 217-221

app/modules/conversations/conversation/conversation_service.py (3)

281-282: LGTM! Constructor changes look good.

The analytics service is properly injected through the constructor and stored as an instance variable.

Also applies to: 291-291


294-316: LGTM! Create method changes are consistent.

The create method properly handles the analytics service parameter and passes it to the constructor.


422-430: LGTM! Analytics integration is consistent.

The analytics service is used appropriately to track conversation events with relevant metadata.

Also applies to: 479-483, 610-614, 767-771

@@ -14,6 +16,7 @@
async def parse_directory(
repo_details: ParsingRequest,
db: Session = Depends(get_db),
analytics_service: AnalyticsService = Depends(get_analytics_service),
user=Depends(AuthService.check_auth),
):
return await ParsingController.parse_directory(repo_details, db, user)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Pass analytics_service to ParsingController.parse_directory.

The analytics_service parameter is added but not passed to the controller method.

Apply this diff to fix the issue:

-    return await ParsingController.parse_directory(repo_details, db, user)
+    return await ParsingController.parse_directory(repo_details, db, analytics_service, user)
📝 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
return await ParsingController.parse_directory(repo_details, db, user)
return await ParsingController.parse_directory(repo_details, db, analytics_service, user)

@@ -42,7 +43,8 @@ def process_parsing(
) -> None:
logger.info(f"Task received: Starting parsing process for project {project_id}")
try:
parsing_service = ParsingService(self.db, user_id)
analytics_service = get_analytics_service()
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix analytics service initialization in Celery task.

The get_analytics_service function requires a FastAPI request object, but it's being called in a Celery task where there is no request context. This will cause a runtime error.

Consider these solutions:

  1. Initialize analytics service directly:
-        analytics_service = get_analytics_service()
+        analytics_service = init_analytics_service()
  1. Or better, initialize it once at task startup and store in task instance:
 class BaseTask(Task):
     _db = None
+    _analytics_service = None
 
     @property
     def db(self):
         if self._db is None:
             self._db = SessionLocal()
         return self._db
 
+    @property
+    def analytics_service(self):
+        if self._analytics_service is None:
+            self._analytics_service = init_analytics_service()
+        return self._analytics_service
+
     def after_return(self, *args, **kwargs):
         if self._db is not None:
             self._db.close()
             self._db = None
+        self._analytics_service = None

 @celery_app.task(...)
 def process_parsing(...):
     try:
-        analytics_service = get_analytics_service()
+        analytics_service = self.analytics_service
📝 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
analytics_service = get_analytics_service()
class BaseTask(Task):
_db = None
_analytics_service = None
@property
def db(self):
if self._db is None:
self._db = SessionLocal()
return self._db
@property
def analytics_service(self):
if self._analytics_service is None:
self._analytics_service = init_analytics_service()
return self._analytics_service
def after_return(self, *args, **kwargs):
if self._db is not None:
self._db.close()
self._db = None
self._analytics_service = None
@celery_app.task(...)
def process_parsing(...):
try:
analytics_service = self.analytics_service
# ... rest of the task implementation

Comment on lines +34 to +35
from contextlib import asynccontextmanager
from app.core.dependencies import init_state, init_analytics_service
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unused import.

The init_analytics_service import is not used in this file.

Apply this diff to remove the unused import:

-from app.core.dependencies import init_state, init_analytics_service
+from app.core.dependencies import init_state
📝 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
from contextlib import asynccontextmanager
from app.core.dependencies import init_state, init_analytics_service
from contextlib import asynccontextmanager
from app.core.dependencies import init_state
🧰 Tools
🪛 Ruff (0.8.2)

35-35: app.core.dependencies.init_analytics_service imported but unused

Remove unused import: app.core.dependencies.init_analytics_service

(F401)

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