{"id":15012860,"url":"https://github.com/dendrite-systems/dendrite-python-sdk","last_synced_at":"2025-04-09T11:06:27.183Z","repository":{"id":220850148,"uuid":"751879783","full_name":"dendrite-systems/dendrite-python-sdk","owner":"dendrite-systems","description":"Tools to build web AI agents that can authenticate, interact with and extract data from any website.","archived":false,"fork":false,"pushed_at":"2025-01-08T09:08:38.000Z","size":35631,"stargazers_count":266,"open_issues_count":5,"forks_count":13,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-04T19:34:11.069Z","etag":null,"topics":["agent","ai","aiagent","rpa","scraping","web","webagent"],"latest_commit_sha":null,"homepage":"https://dendrite.systems","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dendrite-systems.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-02T14:28:45.000Z","updated_at":"2025-04-04T16:35:53.000Z","dependencies_parsed_at":"2024-02-04T21:09:09.261Z","dependency_job_id":"0c2cbfd3-713d-4ce4-92d0-221a41fe0dc2","html_url":"https://github.com/dendrite-systems/dendrite-python-sdk","commit_stats":{"total_commits":114,"total_committers":4,"mean_commits":28.5,"dds":0.4122807017543859,"last_synced_commit":"27c9dab6baae53aabf65cf57615b6162397c64b2"},"previous_names":["charlesmaddock/dendrite-python-sdk","dendrite-agent/dendrite-python-sdk","dendrite-systems/dendrite-python-sdk"],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dendrite-systems%2Fdendrite-python-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dendrite-systems%2Fdendrite-python-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dendrite-systems%2Fdendrite-python-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dendrite-systems%2Fdendrite-python-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dendrite-systems","download_url":"https://codeload.github.com/dendrite-systems/dendrite-python-sdk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248027407,"owners_count":21035594,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","ai","aiagent","rpa","scraping","web","webagent"],"created_at":"2024-09-24T19:43:20.386Z","updated_at":"2025-04-09T11:06:27.149Z","avatar_url":"https://github.com/dendrite-systems.png","language":"Python","readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://dendrite.systems\"\u003e\u003cimg src=\"https://img.shields.io/badge/Website-dendrite.systems-blue?style=for-the-badge\u0026logo=google-chrome\" alt=\"Dendrite Homepage\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://docs.dendrite.systems\"\u003e\u003cimg src=\"https://img.shields.io/badge/Docs-docs.dendrite.systems-orange?style=for-the-badge\u0026logo=bookstack\" alt=\"Docs\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://discord.gg/ETPBdXU3kx\"\u003e\u003cimg src=\"https://img.shields.io/badge/Discord-Join%20Us-7289DA?style=for-the-badge\u0026logo=discord\u0026logoColor=white\" alt=\"Discord\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003e **Notice:** The Dendrite SDK is not under active development anymore. However, the project will remain fully open source so that you and others can learn from it. Feel free to fork, study, or adapt this code for your own projects as you wish – reach out to us on Discord if you have questions! We love chatting about web AI agents. 🤖\n\n## What is Dendrite?\n\n#### Dendrite is a framework that makes it easy for web AI agents to browse the internet just like humans do. Use Dendrite to:\n\n- 👆🏼 Interact with elements\n- 💿 Extract structured data\n- 🔓 Authenticate on websites\n- ↕️ Download/upload files\n- 🚫 Browse without getting blocked\n\n\n#### A simple outlook integration\n\nWith Dendrite it's easy to create web interaction tools for your agent.\n\nHere's how you can send an email:\n\n```python\nfrom dendrite import AsyncDendrite\n\n\nasync def send_email(to, subject, message):\n    client = AsyncDendrite(auth=\"outlook.live.com\")\n\n    # Navigate\n    await client.goto(\n        \"https://outlook.live.com/mail/0/\", expected_page=\"An email inbox\"\n    )\n\n    # Create new email and populate fields\n    await client.click(\"The new email button\")\n    await client.fill(\"The recipient field\", to)\n    await client.press(\"Enter\")\n    await client.fill(\"The subject field\", subject)\n    await client.fill(\"The message field\", message)\n\n    # Send email\n    await client.press(\"Enter\", hold_cmd=True)\n\n\nif __name__ == \"__main__\":\n    import asyncio\n\n    asyncio.run(send_email(\"test@example.com\", \"Hello\", \"This is a test email\"))\n\n```\n\nYou'll need to add your own Anthropic key or [configure which LLMs to use yourself](https://docs.dendrite.systems/concepts/config).\n\n\n```.env\nANTHROPIC_API_KEY=sk-...\n```\n\nTo **authenticate** on any web service with Dendrite, follow these steps:\n\n1. Run the authentication command\n\n  ```bash\n  dendrite auth --url outlook.live.com\n  ```\n\n2. This command will open a browser that you'll be able to login with.\n\n3. After you've logged in, press enter in your terminal. This will save your cookies locally so that they can be used in your code.\n\nRead more about authentication [in our docs](https://docs.dendrite.systems/examples/authentication).\n\n## Quickstart\n\n```\npip install dendrite \u0026\u0026 dendrite install\n```\n\n#### Simple navigation and interaction\n\n```python\nfrom dendrite import AsyncDendrite\n\nasync def main():\n    client = AsyncDendrite()\n\n    await client.goto(\"https://google.com\")\n    await client.fill(\"Search field\", \"Hello world\")\n    await client.press(\"Enter\")\n\nif __name__ == \"__main__\":\n    import asyncio\n    asyncio.run(main())\n```\n\nIn the example above, we simply go to Google, populate the search field with \"Hello world\" and simulate a keypress on Enter. It's a simple example that starts to explore the endless possibilities with Dendrite. Now you can create tools for your agents that have access to the full web without depending on APIs.\n\n## More Examples\n\n### Get any page as markdown\n\nThis is a simple example of how to get any page as markdown, great for feeding to an LLM.\n\n```python\nfrom dendrite import AsyncDendrite\nfrom dotenv import load_dotenv\n\nasync def main():\n    browser = AsyncDendrite()\n\n    await browser.goto(\"https://dendrite.systems\")\n    await browser.wait_for(\"the page to load\")\n\n    # Get the entire page as markdown\n    md = await browser.markdown()\n    print(md)\n    print(\"=\" * 200)\n\n    # Only get a certain part of the page as markdown\n    data_extraction_md = await browser.markdown(\"the part about data extraction\")\n    print(data_extraction_md)\n\nif __name__ == \"__main__\":\n    import asyncio\n    asyncio.run(main())\n```\n\n### Get Company Data from Y Combinator\n\nThe classic web data extraction test, made easy:\n\n```python\nfrom dendrite import AsyncDendrite\nimport pprint\nimport asyncio\n\n\nasync def main():\n    browser = AsyncDendrite()\n\n    # Navigate\n    await browser.goto(\"https://www.ycombinator.com/companies\")\n\n    # Find and fill the search field with \"AI agent\"\n    await browser.fill(\n        \"Search field\", value=\"AI agent\"\n    )  # Element selector cached since before\n    await browser.press(\"Enter\")\n\n    # Extract startups with natural language description\n    # Once created by our agent, the same script will be cached and reused\n    startups = await browser.extract(\n        \"All companies. Return a list of dicts with name, location, description and url\"\n    )\n    pprint.pprint(startups, indent=2)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n\n```\n\nreturns \n```\n[ { 'description': 'Book accommodations around the world.',\n    'location': 'San Francisco, CA, USA',\n    'name': 'Airbnb',\n    'url': 'https://www.ycombinator.com/companies/airbnb'},\n  { 'description': 'Digital Analytics Platform',\n    'location': 'San Francisco, CA, USA',\n    'name': 'Amplitude',\n    'url': 'https://www.ycombinator.com/companies/amplitude'},\n...\n] }\n```\n\n\n### Extract Data from Google Analytics\n\nHere's how to get the amount of monthly visitors from Google Analytics using the `extract` function:\n\n```python\nasync def get_visitor_count() -\u003e int:\n    client = AsyncDendrite(auth=\"analytics.google.com\")\n\n    await client.goto(\n      \"https://analytics.google.com/analytics/web\",\n      expected_page=\"Google Analytics dashboard\"\n    )\n\n    # The Dendrite extract agent will create a web script that is cached\n    # and reused. It will self-heal when the website updates\n    visitor_count = await client.extract(\"The amount of visitors this month\", int)\n    return visitor_count\n```\n\n### Download Bank Transactions\n\nHere's tool that allows our AI agent to download our bank's monthly transactions so that they can be analyzed and compiled into a report.\n\n```python\nfrom dendrite import AsyncDendrite\n\nasync def get_transactions() -\u003e str:\n    client = AsyncDendrite(auth=\"mercury.com\")\n\n    # Navigate and wait for loading\n    await client.goto(\n      \"https://app.mercury.com/transactions\",\n      expected_page=\"Dashboard with transactions\"\n    )\n    await client.wait_for(\"The transactions to finish loading\")\n\n    # Modify filters\n    await client.click(\"The 'add filter' button\")\n    await client.click(\"The 'show transactions for' dropdown\")\n    await client.click(\"The 'this month' option\")\n\n    # Download file\n    await client.click(\"The 'export filtered' button\")\n    transactions = await client.get_download()\n\n    # Save file locally\n    path = \"files/transactions.xlsx\"\n    await transactions.save_as(path)\n\n    return path\n\nasync def analyze_transactions(path: str):\n    ... # Analyze the transactions with LLM of our choice\n```\n\n\n## Documentation\n\n[Read the full docs here](https://docs.dendrite.systems)\n\n[Find more advanced examples in our docs.](https://docs.dendrite.systems/examples)\n\n## Remote Browsers\n\nWhen you want to scale up your AI agents, we support using browsers hosted by Browserbase. This way you can run many agents in parallel without having to worry about the infrastructure.\n\nTo start using Browserbase just swap out the `AsyncDendrite` class with `AsyncDendriteRemoteBrowser` and add your Browserbase API key and project id, either in the code or in a `.env` file like this:\n\n```bash\n# ... previous keys\nBROWSERBASE_API_KEY=\nBROWSERBASE_PROJECT_ID=\n```\n\n```python\n# from dendrite import AsyncDendrite\nfrom dendrite import AsyncDendriteRemoteBrowser\n\nasync def main():\n    # client = AsyncDendrite(...)\n    client = AsyncDendriteRemoteBrowser(\n        # Use interchangeably with the AsyncDendrite class\n        browserbase_api_key=\"...\", # or specify the browsebase keys in the .env file\n        browserbase_project_id=\"...\"\n    )\n    ...\n\nif __name__ == \"__main__\":\n    import asyncio\n    asyncio.run(main())\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdendrite-systems%2Fdendrite-python-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdendrite-systems%2Fdendrite-python-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdendrite-systems%2Fdendrite-python-sdk/lists"}