Skip to content

Commit

Permalink
Header update
Browse files Browse the repository at this point in the history
  • Loading branch information
jahwag committed Jul 23, 2024
1 parent f61fefc commit c874870
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 302 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "claudesync"
version = "0.3.5"
version = "0.3.6"
authors = [
{name = "Jahziah Wagner", email = "[email protected]"},
]
Expand Down
4 changes: 2 additions & 2 deletions src/claudesync/cli/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def logout(config):
click.echo("Logged out successfully.")


@click.command()
@api.command()
@click.option("--delay", type=float, required=True, help="Upload delay in seconds")
@click.pass_obj
@handle_errors
Expand All @@ -54,7 +54,7 @@ def ratelimit(config, delay):
click.echo(f"Upload delay set to {delay} seconds.")


@click.command()
@api.command()
@click.option("--size", type=int, required=True, help="Maximum file size in bytes")
@click.pass_obj
@handle_errors
Expand Down
1 change: 1 addition & 0 deletions src/claudesync/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .organization import organization
from .project import project
from .sync import ls, sync, schedule
from .api import ratelimit, max_filesize

click_completion.init()

Expand Down
13 changes: 13 additions & 0 deletions src/claudesync/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,16 @@ def get_headers(self):
dict: The current headers configuration.
"""
return self.config.get("headers", {})

def update_cookies(self, new_cookies):
"""
Updates the cookies configuration with new values.
Args:
new_cookies (dict): A dictionary containing the new cookie key-value pairs to update or add.
This method updates the existing cookies with the new values provided, adds any new cookies,
and then saves the updated configuration to the file.
"""
self.config.setdefault("cookies", {}).update(new_cookies)
self._save_config()
18 changes: 10 additions & 8 deletions src/claudesync/provider_factory.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from .providers.claude_ai import ClaudeAIProvider

# src/claudesync/provider_factory.py

# Import other providers here as they are added
from .providers.base_provider import BaseProvider
from .providers.claude_ai import ClaudeAIProvider


def get_provider(provider_name=None, session_key=None):
def get_provider(provider_name=None, session_key=None) -> BaseProvider:
"""
Retrieve an instance of a provider class based on the provider name and session key.
Expand All @@ -13,12 +13,14 @@ def get_provider(provider_name=None, session_key=None):
name is specified but not found in the registry, it raises a ValueError. If a session key is provided, it
is passed to the provider class constructor.
Args: provider_name (str, optional): The name of the provider to retrieve. If None, returns a list of available
provider names. session_key (str, optional): The session key to be used by the provider for authentication.
Defaults to None.
Args:
provider_name (str, optional): The name of the provider to retrieve. If None, returns a list of available
provider names.
session_key (str, optional): The session key to be used by the provider for authentication.
Defaults to None.
Returns:
object: An instance of the requested provider class if both provider_name and session_key are provided.
BaseProvider: An instance of the requested provider class if both provider_name and session_key are provided.
list: A list of available provider names if provider_name is None.
Raises:
Expand Down
45 changes: 45 additions & 0 deletions src/claudesync/providers/base_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# src/claudesync/providers/base_provider.py

from abc import ABC, abstractmethod


class BaseProvider(ABC):
@abstractmethod
def login(self):
"""Authenticate with the provider and return a session key."""
pass

@abstractmethod
def get_organizations(self):
"""Retrieve a list of organizations the user is a member of."""
pass

@abstractmethod
def get_projects(self, organization_id, include_archived=False):
"""Retrieve a list of projects for a specified organization."""
pass

@abstractmethod
def list_files(self, organization_id, project_id):
"""List all files within a specified project and organization."""
pass

@abstractmethod
def upload_file(self, organization_id, project_id, file_name, content):
"""Upload a file to a specified project within an organization."""
pass

@abstractmethod
def delete_file(self, organization_id, project_id, file_uuid):
"""Delete a file from a specified project within an organization."""
pass

@abstractmethod
def archive_project(self, organization_id, project_id):
"""Archive a specified project within an organization."""
pass

@abstractmethod
def create_project(self, organization_id, name, description=""):
"""Create a new project within a specified organization."""
pass
56 changes: 33 additions & 23 deletions src/claudesync/providers/claude_ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import click
import requests

from .base_provider import BaseProvider
from ..config_manager import ConfigManager
from ..exceptions import ProviderError

logger = logging.getLogger(__name__)


class ClaudeAIProvider:
class ClaudeAIProvider(BaseProvider):
"""
A provider class for interacting with the Claude AI API.
Expand Down Expand Up @@ -61,30 +62,36 @@ def _configure_logging(self):
) # Set logger instance to the specified log level

def _make_request(self, method, endpoint, **kwargs):
"""
Sends a request to the specified endpoint using the given HTTP method.
This method constructs a request to the Claude AI API, appending the specified endpoint to the base URL.
It sets up common headers and cookies for the request, including a session key for authentication.
Additional headers can be provided through `kwargs`. The method logs the request and response details
and handles common HTTP errors and JSON parsing errors.
Args:
method (str): The HTTP method to use for the request (e.g., 'GET', 'POST').
endpoint (str): The API endpoint to which the request is sent.
**kwargs: Arbitrary keyword arguments. Can include 'headers' to add or override default headers,
and any other request parameters.
Returns:
dict or None: The parsed JSON response from the API if the response contains content; otherwise, None.
Raises:
ProviderError: If the request fails, if the response status code indicates an error,
or if the response cannot be parsed as JSON.
"""
url = f"{self.BASE_URL}{endpoint}"
headers = self.config.get_headers()
cookies = {"sessionKey": self.session_key}
cookies = self.config.get("cookies", {})

# Update headers
headers.update(
{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
"Origin": "https://claude.ai",
"Referer": "https://claude.ai/projects",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "en-US,en;q=0.5",
"anthropic-client-sha": "unknown",
"anthropic-client-version": "unknown",
"Connection": "keep-alive",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
}
)

# Merge cookies
cookies.update(
{
"sessionKey": self.session_key,
"CH-prefers-color-scheme": "dark",
"anthropic-consent-preferences": '{"analytics":true,"marketing":true}',
}
)

if "headers" in kwargs:
headers.update(kwargs.pop("headers"))
Expand All @@ -106,6 +113,9 @@ def _make_request(self, method, endpoint, **kwargs):
f"Response content: {response.text[:1000]}..."
) # Log first 1000 characters of response

# Update cookies with any new values from the response
self.config.update_cookies(response.cookies.get_dict())

response.raise_for_status()

if not response.content:
Expand Down
Loading

0 comments on commit c874870

Please sign in to comment.