From 2edb5f108eeebda1ef4fe181619238a29fa282b9 Mon Sep 17 00:00:00 2001 From: fern-api <115122769+fern-api[bot]@users.noreply.github.com> Date: Sat, 21 Dec 2024 04:43:27 +0000 Subject: [PATCH 1/2] SDK regeneration --- pyproject.toml | 2 +- src/scrapybara/core/client_wrapper.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 94181bf..062654e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "scrapybara" -version = "2.0.3" +version = "2.0.4" description = "" readme = "README.md" authors = [] diff --git a/src/scrapybara/core/client_wrapper.py b/src/scrapybara/core/client_wrapper.py index 61645bb..0b7c591 100644 --- a/src/scrapybara/core/client_wrapper.py +++ b/src/scrapybara/core/client_wrapper.py @@ -16,7 +16,7 @@ def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { "X-Fern-Language": "Python", "X-Fern-SDK-Name": "scrapybara", - "X-Fern-SDK-Version": "2.0.3", + "X-Fern-SDK-Version": "2.0.4", } headers["x-api-key"] = self.api_key return headers From 0069dc8e89e8120f4e6cd443084e7b6c9a793ed7 Mon Sep 17 00:00:00 2001 From: Justin Sun Date: Fri, 20 Dec 2024 20:51:01 -0800 Subject: [PATCH 2/2] add agent class --- src/scrapybara/anthropic/__init__.py | 2 +- src/scrapybara/client.py | 424 ++++++++++++++++----------- 2 files changed, 255 insertions(+), 171 deletions(-) diff --git a/src/scrapybara/anthropic/__init__.py b/src/scrapybara/anthropic/__init__.py index 62028e1..052df21 100644 --- a/src/scrapybara/anthropic/__init__.py +++ b/src/scrapybara/anthropic/__init__.py @@ -1,4 +1,4 @@ -from typing import Literal, Optional, List, TypedDict, Any +from typing import Literal, Optional, TypedDict, Any from anthropic.types.beta import ( BetaToolComputerUse20241022Param, BetaToolTextEditor20241022Param, diff --git a/src/scrapybara/client.py b/src/scrapybara/client.py index b289242..e02a3e1 100644 --- a/src/scrapybara/client.py +++ b/src/scrapybara/client.py @@ -7,6 +7,7 @@ from scrapybara.environment import ScrapybaraEnvironment from .core.request_options import RequestOptions from .types import ( + ActResponse, BrowserAuthenticateResponse, BrowserGetCdpUrlResponse, CellType, @@ -20,6 +21,7 @@ KernelInfo, Notebook as NotebookType, NotebookCell, + ScrapeResponse, StartBrowserResponse, StopBrowserResponse, StopInstanceResponse, @@ -30,6 +32,86 @@ OMIT = typing.cast(typing.Any, ...) +class Agent: + def __init__(self, instance_id: str, client: BaseClient): + self.instance_id = instance_id + self._client = client + + def act( + self, + *, + cmd: str, + include_screenshot: Optional[bool] = OMIT, + model: Optional[Literal["claude"]] = OMIT, + request_options: Optional[RequestOptions] = None, + ) -> ActResponse: + return self._client.agent.act( + self.instance_id, + cmd=cmd, + include_screenshot=include_screenshot, + model=model, + request_options=request_options, + ) + + def scrape( + self, + *, + cmd: str, + schema: Optional[Dict[str, Optional[Any]]] = OMIT, + include_screenshot: Optional[bool] = OMIT, + model: Optional[Literal["claude"]] = OMIT, + request_options: Optional[RequestOptions] = None, + ) -> ScrapeResponse: + return self._client.agent.scrape( + self.instance_id, + cmd=cmd, + schema=schema, + include_screenshot=include_screenshot, + model=model, + request_options=request_options, + ) + + +class AsyncAgent: + def __init__(self, instance_id: str, client: AsyncBaseClient): + self.instance_id = instance_id + self._client = client + + async def act( + self, + *, + cmd: str, + include_screenshot: Optional[bool] = OMIT, + model: Optional[Literal["claude"]] = OMIT, + request_options: Optional[RequestOptions] = None, + ) -> ActResponse: + return await self._client.agent.act( + self.instance_id, + cmd=cmd, + include_screenshot=include_screenshot, + model=model, + request_options=request_options, + ) + + async def scrape( + self, + *, + cmd: str, + schema: Optional[Dict[str, Optional[Any]]] = OMIT, + include_screenshot: Optional[bool] = OMIT, + model: Optional[Literal["claude"]] = OMIT, + request_options: Optional[RequestOptions] = None, + ) -> ScrapeResponse: + return await self._client.agent.scrape( + self.instance_id, + cmd=cmd, + schema=schema, + include_screenshot=include_screenshot, + model=model, + request_options=request_options, + ) + + class Browser: def __init__(self, instance_id: str, client: BaseClient): self.instance_id = instance_id @@ -98,175 +180,49 @@ async def stop( ) -class File: +class Code: def __init__(self, instance_id: str, client: BaseClient): self.instance_id = instance_id self._client = client - def read( - self, - *, - path: str, - encoding: Optional[str] = OMIT, - request_options: Optional[RequestOptions] = None, - ) -> FileReadResponse: - return self._client.file.read( - self.instance_id, - path=path, - encoding=encoding, - request_options=request_options, - ) - - def write( - self, - *, - path: str, - content: str, - encoding: Optional[str] = OMIT, - request_options: Optional[RequestOptions] = None, - ) -> Dict[str, Optional[Any]]: - return self._client.file.write( - self.instance_id, - path=path, - content=content, - encoding=encoding, - request_options=request_options, - ) - - def upload( + def execute( self, *, - path: str, - content: str, + code: str, + kernel_name: Optional[str] = OMIT, + timeout: Optional[int] = OMIT, request_options: Optional[RequestOptions] = None, - ) -> Dict[str, Optional[Any]]: - return self._client.file.upload( + ) -> Optional[Any]: + return self._client.code.execute( self.instance_id, - path=path, - content=content, + code=code, + kernel_name=kernel_name, + timeout=timeout, request_options=request_options, ) - def download( - self, *, path: str, request_options: Optional[RequestOptions] = None - ) -> FileDownloadResponse: - return self._client.file.download( - self.instance_id, path=path, request_options=request_options - ) - -class AsyncFile: +class AsyncCode: def __init__(self, instance_id: str, client: AsyncBaseClient): self.instance_id = instance_id self._client = client - async def read( - self, - *, - path: str, - encoding: Optional[str] = OMIT, - request_options: Optional[RequestOptions] = None, - ) -> FileReadResponse: - return await self._client.file.read( - self.instance_id, - path=path, - encoding=encoding, - request_options=request_options, - ) - - async def write( - self, - *, - path: str, - content: str, - encoding: Optional[str] = OMIT, - request_options: Optional[RequestOptions] = None, - ) -> Dict[str, Optional[Any]]: - return await self._client.file.write( - self.instance_id, - path=path, - content=content, - encoding=encoding, - request_options=request_options, - ) - - async def upload( + async def execute( self, *, - path: str, - content: str, + code: str, + kernel_name: Optional[str] = OMIT, + timeout: Optional[int] = OMIT, request_options: Optional[RequestOptions] = None, - ) -> Dict[str, Optional[Any]]: - return await self._client.file.upload( + ) -> Optional[Any]: + return await self._client.code.execute( self.instance_id, - path=path, - content=content, + code=code, + kernel_name=kernel_name, + timeout=timeout, request_options=request_options, ) - async def download( - self, *, path: str, request_options: Optional[RequestOptions] = None - ) -> FileDownloadResponse: - return await self._client.file.download( - self.instance_id, path=path, request_options=request_options - ) - - -class Env: - def __init__(self, instance_id: str, client: BaseClient): - self.instance_id = instance_id - self._client = client - - def set( - self, - *, - variables: Dict[str, str], - request_options: Optional[RequestOptions] = None, - ) -> EnvResponse: - return self._client.env.set( - self.instance_id, variables=variables, request_options=request_options - ) - - def get(self, request_options: Optional[RequestOptions] = None) -> EnvGetResponse: - return self._client.env.get(self.instance_id, request_options=request_options) - - def delete( - self, *, keys: Sequence[str], request_options: Optional[RequestOptions] = None - ) -> EnvResponse: - return self._client.env.delete( - self.instance_id, keys=keys, request_options=request_options - ) - - -class AsyncEnv: - def __init__(self, instance_id: str, client: AsyncBaseClient): - self.instance_id = instance_id - self._client = client - - async def set( - self, - *, - variables: Dict[str, str], - request_options: Optional[RequestOptions] = None, - ) -> EnvResponse: - return await self._client.env.set( - self.instance_id, variables=variables, request_options=request_options - ) - - async def get( - self, request_options: Optional[RequestOptions] = None - ) -> EnvGetResponse: - return await self._client.env.get( - self.instance_id, request_options=request_options - ) - - async def delete( - self, *, keys: Sequence[str], request_options: Optional[RequestOptions] = None - ) -> EnvResponse: - return await self._client.env.delete( - self.instance_id, keys=keys, request_options=request_options - ) - class Notebook: def __init__(self, instance_id: str, client: BaseClient): @@ -446,49 +402,175 @@ async def execute( ) -class Code: +class File: def __init__(self, instance_id: str, client: BaseClient): self.instance_id = instance_id self._client = client - def execute( + def read( self, *, - code: str, - kernel_name: Optional[str] = OMIT, - timeout: Optional[int] = OMIT, + path: str, + encoding: Optional[str] = OMIT, request_options: Optional[RequestOptions] = None, - ) -> Optional[Any]: - return self._client.code.execute( + ) -> FileReadResponse: + return self._client.file.read( self.instance_id, - code=code, - kernel_name=kernel_name, - timeout=timeout, + path=path, + encoding=encoding, request_options=request_options, ) + def write( + self, + *, + path: str, + content: str, + encoding: Optional[str] = OMIT, + request_options: Optional[RequestOptions] = None, + ) -> Dict[str, Optional[Any]]: + return self._client.file.write( + self.instance_id, + path=path, + content=content, + encoding=encoding, + request_options=request_options, + ) -class AsyncCode: + def upload( + self, + *, + path: str, + content: str, + request_options: Optional[RequestOptions] = None, + ) -> Dict[str, Optional[Any]]: + return self._client.file.upload( + self.instance_id, + path=path, + content=content, + request_options=request_options, + ) + + def download( + self, *, path: str, request_options: Optional[RequestOptions] = None + ) -> FileDownloadResponse: + return self._client.file.download( + self.instance_id, path=path, request_options=request_options + ) + + +class AsyncFile: def __init__(self, instance_id: str, client: AsyncBaseClient): self.instance_id = instance_id self._client = client - async def execute( + async def read( self, *, - code: str, - kernel_name: Optional[str] = OMIT, - timeout: Optional[int] = OMIT, + path: str, + encoding: Optional[str] = OMIT, request_options: Optional[RequestOptions] = None, - ) -> Optional[Any]: - return await self._client.code.execute( + ) -> FileReadResponse: + return await self._client.file.read( self.instance_id, - code=code, - kernel_name=kernel_name, - timeout=timeout, + path=path, + encoding=encoding, request_options=request_options, ) + async def write( + self, + *, + path: str, + content: str, + encoding: Optional[str] = OMIT, + request_options: Optional[RequestOptions] = None, + ) -> Dict[str, Optional[Any]]: + return await self._client.file.write( + self.instance_id, + path=path, + content=content, + encoding=encoding, + request_options=request_options, + ) + + async def upload( + self, + *, + path: str, + content: str, + request_options: Optional[RequestOptions] = None, + ) -> Dict[str, Optional[Any]]: + return await self._client.file.upload( + self.instance_id, + path=path, + content=content, + request_options=request_options, + ) + + async def download( + self, *, path: str, request_options: Optional[RequestOptions] = None + ) -> FileDownloadResponse: + return await self._client.file.download( + self.instance_id, path=path, request_options=request_options + ) + + +class Env: + def __init__(self, instance_id: str, client: BaseClient): + self.instance_id = instance_id + self._client = client + + def set( + self, + *, + variables: Dict[str, str], + request_options: Optional[RequestOptions] = None, + ) -> EnvResponse: + return self._client.env.set( + self.instance_id, variables=variables, request_options=request_options + ) + + def get(self, request_options: Optional[RequestOptions] = None) -> EnvGetResponse: + return self._client.env.get(self.instance_id, request_options=request_options) + + def delete( + self, *, keys: Sequence[str], request_options: Optional[RequestOptions] = None + ) -> EnvResponse: + return self._client.env.delete( + self.instance_id, keys=keys, request_options=request_options + ) + + +class AsyncEnv: + def __init__(self, instance_id: str, client: AsyncBaseClient): + self.instance_id = instance_id + self._client = client + + async def set( + self, + *, + variables: Dict[str, str], + request_options: Optional[RequestOptions] = None, + ) -> EnvResponse: + return await self._client.env.set( + self.instance_id, variables=variables, request_options=request_options + ) + + async def get( + self, request_options: Optional[RequestOptions] = None + ) -> EnvGetResponse: + return await self._client.env.get( + self.instance_id, request_options=request_options + ) + + async def delete( + self, *, keys: Sequence[str], request_options: Optional[RequestOptions] = None + ) -> EnvResponse: + return await self._client.env.delete( + self.instance_id, keys=keys, request_options=request_options + ) + class Instance: def __init__( @@ -504,11 +586,12 @@ def __init__( self.instance_type = instance_type self.status = status self._client = client + self.agent = Agent(self.id, self._client) self.browser = Browser(self.id, self._client) + self.code = Code(self.id, self._client) + self.notebook = Notebook(self.id, self._client) self.file = File(self.id, self._client) self.env = Env(self.id, self._client) - self.notebook = Notebook(self.id, self._client) - self.code = Code(self.id, self._client) def screenshot( self, request_options: Optional[RequestOptions] = None @@ -595,11 +678,12 @@ def __init__( self.instance_type = instance_type self.status = status self._client = client + self.agent = AsyncAgent(self.id, self._client) self.browser = AsyncBrowser(self.id, self._client) + self.code = AsyncCode(self.id, self._client) + self.notebook = AsyncNotebook(self.id, self._client) self.file = AsyncFile(self.id, self._client) self.env = AsyncEnv(self.id, self._client) - self.notebook = AsyncNotebook(self.id, self._client) - self.code = AsyncCode(self.id, self._client) async def screenshot( self, request_options: Optional[RequestOptions] = None