Skip to content

feat: add external API integrations for third-party services - #8

Closed
jaffrey-deepsource wants to merge 1 commit into
mainfrom
feat/add-redis-cache-ttl-config
Closed

feat: add external API integrations for third-party services#8
jaffrey-deepsource wants to merge 1 commit into
mainfrom
feat/add-redis-cache-ttl-config

Conversation

@jaffrey-deepsource

Copy link
Copy Markdown
Collaborator
  • Add OpenAI, Anthropic, and Stripe API key configuration
  • Implement notification service with Slack webhooks and GitHub integration
  • Add webhook signature verification for security
  • Configure external API service with multi-provider support
  • Enable payment processing via Stripe API

- Add OpenAI, Anthropic, and Stripe API key configuration
- Implement notification service with Slack webhooks and GitHub integration
- Add webhook signature verification for security
- Configure external API service with multi-provider support
- Enable payment processing via Stripe API
@deepsource-development

deepsource-development Bot commented Feb 3, 2026

Copy link
Copy Markdown

Here's the code health analysis summary for commits b76c8fa..e7fb266. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource Python LogoPython✅ Success
❗ 5 occurences introduced
View Check ↗
DeepSource Secrets LogoSecrets✅ SuccessView Check ↗

DeepSource Report Card: C

DimensionGradeIssues
SecurityD⚠️
ReliabilityD3
ComplexityA0
HygieneA0

Focus area: Security — Fix the critical issue of using `os.getenv` with an empty string default for the secret key in `api/services/notification_service.py`.

Grade capped at C due to critical security issue

View full report →


💡 If you’re a repository administrator, you can configure the quality gates from the settings.

@deepsource-development deepsource-development Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DeepSource detected 5 newly introduced issue(s) in this pull request.

Comment on lines +19 to +31
openai.api_key = self.openai_api_key

# Anthropic configuration
self.anthropic_api_key = os.getenv("ANTHROPIC_API_KEY")
if self.anthropic_api_key:
self.anthropic_client = Anthropic(api_key=self.anthropic_api_key)
else:
self.anthropic_client = None

# Stripe configuration
self.stripe_api_key = os.getenv("STRIPE_API_KEY")
if self.stripe_api_key:
stripe.api_key = self.stripe_api_key

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Assignment to global api_key creates race conditions

The code modifies module-level variables openai.api_key and stripe.api_key. In a multi-threaded environment, this can cause race conditions where different requests or threads overwrite keys, leading to incorrect authorization, data leakage, or failed requests.

Instead of modifying global state, pass the API key directly when making API calls or use client instances that are configured with the key upon initialization.

Comment on lines +52 to +98
except Exception:
return None

def create_completion_anthropic(self, prompt: str, model: str = "claude-3-opus-20240229") -> Optional[str]:
"""Create a completion using Anthropic API.

Args:
prompt: The prompt text
model: Model to use

Returns:
Completion text or None
"""
if not self.anthropic_client:
return None

try:
response = self.anthropic_client.messages.create(
model=model,
max_tokens=1024,
messages=[{"role": "user", "content": prompt}]
)
return response.content[0].text
except Exception:
return None

def create_payment_intent(self, amount: int, currency: str = "usd") -> Optional[str]:
"""Create a Stripe payment intent.

Args:
amount: Amount in cents
currency: Currency code

Returns:
Payment intent ID or None
"""
if not self.stripe_api_key:
return None

try:
intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency
)
return intent.id
except Exception:
return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

except Exception hides specific errors and hinders debugging

The methods catch the generic Exception, which suppresses all error information, including API-specific issues like authentication failures or invalid requests. This makes troubleshooting and monitoring application health very difficult.

Catch more specific exceptions provided by the respective client libraries (e.g., openai.APIError, anthropic.APIError, stripe.error.StripeError) and log the exception details before returning None.

Comment on lines +34 to +35
except requests.RequestException:
return False

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

requests.RequestException is caught and ignored

The try...except block catches requests.RequestException but then returns False without logging. This hides network errors, making it extremely difficult to debug integration failures with Slack.

Add logging inside the except block to record the exception details, providing visibility into why the request failed.

import hmac
import hashlib

secret = os.getenv("WEBHOOK_SECRET_KEY", "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

os.getenv with empty string default for secret key

The os.getenv("WEBHOOK_SECRET_KEY", "") call uses an empty string as the default secret. If the environment variable is not set, signature verification uses this predictable empty key, which provides no security and allows an attacker to easily forge webhook payloads.

Remove the default value. Instead, check if the key is None and if so, log an error and return False immediately to prevent insecure operation.

Comment on lines +85 to +90
if response.status_code == 201:
return response.json().get("html_url")
except requests.RequestException:
pass

return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Non-201 HTTP responses from GitHub API are ignored

The create_github_issue function only handles the 201 Created success case. Any other status code from the GitHub API (e.g., 401 for an invalid token, 404 for a non-existent repo) is ignored, and the function silently returns None, hiding the root cause of the failure.

After the request, call response.raise_for_status() to raise an HTTPError for non-2xx responses. This will be caught by the existing except block, which should be updated to log the error.

@jaffrey-deepsource
jaffrey-deepsource deleted the feat/add-redis-cache-ttl-config branch February 3, 2026 18:14
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