{"id":24287610,"url":"https://github.com/rysuds/dunebuggy","last_synced_at":"2025-09-25T08:31:50.909Z","repository":{"id":38273414,"uuid":"471564002","full_name":"rysuds/dunebuggy","owner":"rysuds","description":"Lightweight Python Client for Dune Analytics","archived":false,"fork":false,"pushed_at":"2022-12-12T17:30:04.000Z","size":163,"stargazers_count":24,"open_issues_count":1,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-12-16T00:19:26.537Z","etag":null,"topics":["crypto","data","defi","dune","ethereum","sdk","solana","sql","web3"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","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/rysuds.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}},"created_at":"2022-03-19T01:38:26.000Z","updated_at":"2024-06-20T11:12:35.000Z","dependencies_parsed_at":"2023-01-27T22:46:26.249Z","dependency_job_id":null,"html_url":"https://github.com/rysuds/dunebuggy","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rysuds%2Fdunebuggy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rysuds%2Fdunebuggy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rysuds%2Fdunebuggy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rysuds%2Fdunebuggy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rysuds","download_url":"https://codeload.github.com/rysuds/dunebuggy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234167897,"owners_count":18790199,"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":["crypto","data","defi","dune","ethereum","sdk","solana","sql","web3"],"created_at":"2025-01-16T08:18:57.654Z","updated_at":"2025-09-25T08:31:45.545Z","avatar_url":"https://github.com/rysuds.png","language":"Jupyter Notebook","readme":"\u003c!-- # Dunebuggy\n\n![Alt text](./dune-buggy.svg) --\u003e\n\n\u003ch1 align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"./assets/dune-buggy.svg\" alt=\"Dunebuggy\" width=\"300\" height=\"225\"\u003e\n  \u003cbr\u003e\n  \u003cdiv style=\"sans-serif\"\u003e\u003cb\u003eDunebuggy\u003c/b\u003e\u003c/p\u003e\n\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\nA lightweight (unofficial) Python SDK for \u003ca href=https://dune.com/home\u003e Dune.com\u003c/a\u003e\n\u003cbr\u003e\n\n[Installation](#installation) •\n[Getting started](#getting-started) •\n[Roadmap](#roadmap) •\n[Notes](#notes)\n\n\u003c/div\u003e\n\n## Installation\n\n```sh\npip install dunebuggy\n```\n\n## Getting started\n\n### Retrieving a public query\n\nTo retrieve a query, all we'll need is the `query_id` for the public query we're interested in. In the below example we can take a look at the popular [\"Custom NFT Floor Tracker\" query by @smaroo](https://dune.com/queries/83579) (The `query_id` below can be found in the URL).\n\n```python\nfrom dunebuggy import Dune\n\ndune = Dune()\nquery = dune.fetch_query(83579)\n```\n\n`query` here is a `DuneQuery` object, we can get the `pandas` DataFrame for the query output bf calling `df` on the object\n\n```python\nprint(query.df.head())\n```\n\n\u003cdiv\u003e\n\u003ctable border=\"1\" class=\"dataframe\"\u003e\n  \u003cthead\u003e\n    \u003ctr style=\"text-align: right;\"\u003e\n      \u003cth\u003e\u003c/th\u003e\n      \u003cth\u003eFloor (Approx)\u003c/th\u003e\n      \u003cth\u003eTime Interval\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003e0\u003c/th\u003e\n      \u003ctd\u003e0.122649\u003c/td\u003e\n      \u003ctd\u003e2021-06-01T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e1\u003c/th\u003e\n      \u003ctd\u003e0.130000\u003c/td\u003e\n      \u003ctd\u003e2021-06-02T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e2\u003c/th\u003e\n      \u003ctd\u003e0.193455\u003c/td\u003e\n      \u003ctd\u003e2021-06-03T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e3\u003c/th\u003e\n      \u003ctd\u003e0.189000\u003c/td\u003e\n      \u003ctd\u003e2021-06-04T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e4\u003c/th\u003e\n      \u003ctd\u003e0.189930\u003c/td\u003e\n      \u003ctd\u003e2021-06-05T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\nWe can also take a look at some basic information about the returned query with `query.info`\n\n```python\nprint(query.info)\n```\n\n    {'name': 'Custom NFT Floor Tracker',\n     'author': '@smaroo',\n     'length': 264,\n     'query_id': 83579,\n     'result_id': UUID('e5aef8a0-1453-44d1-a27b-f576ea2b3ba2'),\n     'job_id': UUID('ec680fa9-217f-44c5-b223-56730cd07473'),\n     'columns': ['Time Interval', 'Floor (Approx)']}\n\nSome queries in Dune are \"parameterized\", meaning that the author exposes certain variables for the user to enter custom values. The example query (83579) happens to be parameterized, we can verify this by inspecting `query.parameters`\n\n```python\nprint(query.parameters)\n```\n\n    [QueryParameter(key='Enter NFT Contract Address', type='text', value='xc3f733ca98e0dad0386979eb96fb1722a1a05e69', enumOptions=None),\n     QueryParameter(key='Floor Time Interval', type='enum', value='Day', enumOptions=['Day', 'Hour']),\n     QueryParameter(key='Start Date', type='datetime', value='2021-06-01 00:00:00', enumOptions=None)]\n\nIf you'd like to run this query with your own custom parameters, all we'll need to do is take the parameters from from the initial query, change the values to what we want, and re-fetch the query.\n\nBelow we are replacing the old NFT contract address param with a new one ([the contract address for BAYC](https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d))\n\n```python\nparams = query.parameters\n\n# Replacing with contract address for BAYC\nparams[0].value = 'xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D'\ncustom_query = dune.fetch_query(83579, parameters=params)\n```\n\nNote: You can also create a fresh set of parameters by importing `QueryParameter` from `dunebuggy.models.query` and adding the values to the new object.\n\n```python\nfrom dunebuggy.models.query import QueryParameter\n\nparam_to_change = QueryParameter(\n  key='Enter NFT Contract Address',\n  value='xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',\n)\nparams[0] = param_to_change\ncustom_query = dune.fetch_query(83579, parameters=params)\n```\n\n```python\nprint(custom_query.info)\n```\n\n    {'name': 'Custom NFT Floor Tracker',\n     'author': '@smaroo',\n     'length': 265,\n     'query_id': 83579,\n     'result_id': UUID('42a3c13d-5fbd-42bd-86c0-acc9adcdc803'),\n     'job_id': UUID('9051ebe7-862f-46d0-9999-b4645659ca56'),\n     'columns': ['Time Interval', 'Floor (Approx)']}\n\nNote that the `result_id` and `job_id` here are different, this is because we ran the query with our changed params\n\n```python\nprint(custom_query.parameters)\n```\n\n    [QueryParameter(key='Enter NFT Contract Address', type='text', value='xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D', enumOptions=None),\n    QueryParameter(key='Floor Time Interval', type='enum', value='Day', enumOptions=['Day', 'Hour']),\n    QueryParameter(key='Start Date', type='datetime', value='2021-06-01 00:00:00', enumOptions=None)]\n\n```python\nprint(custom_query.df.head())\n```\n\n\u003cdiv\u003e\n\u003ctable border=\"1\" class=\"dataframe\"\u003e\n  \u003cthead\u003e\n    \u003ctr style=\"text-align: right;\"\u003e\n      \u003cth\u003e\u003c/th\u003e\n      \u003cth\u003eFloor (Approx)\u003c/th\u003e\n      \u003cth\u003eTime Interval\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003e0\u003c/th\u003e\n      \u003ctd\u003e0.8000\u003c/td\u003e\n      \u003ctd\u003e2021-06-01T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e1\u003c/th\u003e\n      \u003ctd\u003e0.8518\u003c/td\u003e\n      \u003ctd\u003e2021-06-02T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e2\u003c/th\u003e\n      \u003ctd\u003e0.8260\u003c/td\u003e\n      \u003ctd\u003e2021-06-03T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e3\u003c/th\u003e\n      \u003ctd\u003e0.7400\u003c/td\u003e\n      \u003ctd\u003e2021-06-04T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e4\u003c/th\u003e\n      \u003ctd\u003e0.8499\u003c/td\u003e\n      \u003ctd\u003e2021-06-05T00:00:00+00:00\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\n### Creating a new query\n\n`dunebuggy` also allows you to create a new using an existing Dune.com account.To login just need to pass in your username/password into the `Dune` object.\n\nYou can verify your login by inspecting your Dune `user_id`\n\n```python\nimport os\n\nusername = os.environ.get('DUNE_USERNAME')\npassword = os.environ.get('DUNE_PASSWORD')\n\ndune = Dune(username=username, password=password)\n# print(dune.user_id)\n```\n\nTo create a query now, all we need to do is pass in a `name`, `query_string` and `dataset_id`\n\nWe can construct the SQL query by using a raw sql string\n\n```python\nquery_string = \"select * from ethereum.transactions\\nLIMIT 100\\n\"\n```\n\nOr we could use a fancy ORM-style library like [pypika](https://github.com/kayak/pypika)\n\n```python\nfrom pypika import Database, Query\n\nethereum = Database('ethereum')\nq = Query.from_(ethereum.transactions).select('*').limit(100)\nquery_string = q.get_sql(quote_char=None)\nprint(query_string)\n```\n\n    'SELECT * FROM ethereum.transactions LIMIT 100'\n\nDune requires us to specify a `dataset_id` for each of their supported blockchain datasets upon query creation. The currently supported datasets are the following:\n\n| Blockchain Dataset | Id  |\n| ------------------ | --- |\n| ETHEREUM           | 4   |\n| XDAI               | 6   |\n| POLYGON            | 7   |\n| OPTIMISM_1         | 8   |\n| OPTIMISM_2         | 10  |\n| BINANCE            | 9   |\n| SOLANA             | 1   |\n\nWe can access these integer codes via the `DatasetId` enum\n\n```python\nfrom dunebuggy.models.constants import DatasetId\ncreated_query = dune.create_query(\"My Query's Name\", query_string, DatasetId.ETHEREUM)\n```\n\nOur created query can be accessed like any other, you can also log into your Dune account as see it there as well!\n\n```python\nprint(created_query.df.head())\n```\n\n\u003cdiv\u003e\n\u003ctable border=\"1\" class=\"dataframe\"\u003e\n  \u003cthead\u003e\n    \u003ctr style=\"text-align: right;\"\u003e\n      \u003cth\u003e\u003c/th\u003e\n      \u003cth\u003eaccess_list\u003c/th\u003e\n      \u003cth\u003eblock_hash\u003c/th\u003e\n      \u003cth\u003eblock_number\u003c/th\u003e\n      \u003cth\u003eblock_time\u003c/th\u003e\n      \u003cth\u003edata\u003c/th\u003e\n      \u003cth\u003efrom\u003c/th\u003e\n      \u003cth\u003egas_limit\u003c/th\u003e\n      \u003cth\u003egas_price\u003c/th\u003e\n      \u003cth\u003egas_used\u003c/th\u003e\n      \u003cth\u003ehash\u003c/th\u003e\n      \u003cth\u003eindex\u003c/th\u003e\n      \u003cth\u003emax_fee_per_gas\u003c/th\u003e\n      \u003cth\u003emax_priority_fee_per_gas\u003c/th\u003e\n      \u003cth\u003enonce\u003c/th\u003e\n      \u003cth\u003epriority_fee_per_gas\u003c/th\u003e\n      \u003cth\u003esuccess\u003c/th\u003e\n      \u003cth\u003eto\u003c/th\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003evalue\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003e0\u003c/th\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x887c665b0c52ccace092d817e984e2e828ef59079295...\u003c/td\u003e\n      \u003ctd\u003e47287\u003c/td\u003e\n      \u003ctd\u003e2015-08-07T08:50:01+00:00\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\xdb312d1d6a2ccc64dd94a3892928bac82b4e8c15\u003c/td\u003e\n      \u003ctd\u003e21000\u003c/td\u003e\n      \u003ctd\u003e100000000000\u003c/td\u003e\n      \u003ctd\u003e21000\u003c/td\u003e\n      \u003ctd\u003e\\xd3e6a2fc34066d20bb83020b1ee95b9dc7919fd242bd...\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x34bb6978c5a1ad68777ad388c6787df53903430c\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e1000000000000000000\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e1\u003c/th\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x4869e218b0a8f5784f16193ac66cbf35c4510ace0c9b...\u003c/td\u003e\n      \u003ctd\u003e48698\u003c/td\u003e\n      \u003ctd\u003e2015-08-07T15:29:53+00:00\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x48040276e9c17ddbe5c8d2976245dcd0235efa43\u003c/td\u003e\n      \u003ctd\u003e90000\u003c/td\u003e\n      \u003ctd\u003e57550496008\u003c/td\u003e\n      \u003ctd\u003e21000\u003c/td\u003e\n      \u003ctd\u003e\\x8ba39f908731171fe96ee4e700e71d170ef8e651fac7...\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\xd8d0549637b65d58e7fb6cbdd11530b399d1ddac\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e100000000000000000000\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e2\u003c/th\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\xab9491b62b16bd928b281a83db82483584c22aeebc0d...\u003c/td\u003e\n      \u003ctd\u003e49051\u003c/td\u003e\n      \u003ctd\u003e2015-08-07T17:03:48+00:00\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x8686578c4f7c75246f548299d6ffdac3b67b5cd1\u003c/td\u003e\n      \u003ctd\u003e90000\u003c/td\u003e\n      \u003ctd\u003e57178423039\u003c/td\u003e\n      \u003ctd\u003e21000\u003c/td\u003e\n      \u003ctd\u003e\\x57f8ba638903d6335e211eb470159587c73316788880...\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x87abffa6b80f712c852a9558120ba6611f0b5e46\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e45150000000000000000\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e3\u003c/th\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x1f9adc2190701ca3085b28252e4f1f467d980f763dad...\u003c/td\u003e\n      \u003ctd\u003e49174\u003c/td\u003e\n      \u003ctd\u003e2015-08-07T17:41:03+00:00\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x18e4ce47483b53040adbab35172c01ef64506e0c\u003c/td\u003e\n      \u003ctd\u003e90000\u003c/td\u003e\n      \u003ctd\u003e58589751415\u003c/td\u003e\n      \u003ctd\u003e21000\u003c/td\u003e\n      \u003ctd\u003e\\xb8280da44f8d35011c3f431f7d1a82213477a4e742de...\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\xfb26ae2d3621829472555fbd11bb2a324b7a5c57\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e10000000000000000000\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e4\u003c/th\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\xf1f392fd197a149afe9f8843d7ba759d1a9f79d1ef62...\u003c/td\u003e\n      \u003ctd\u003e49938\u003c/td\u003e\n      \u003ctd\u003e2015-08-07T21:06:21+00:00\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\xc6bf5b6558f2ee21f2e43d9ff9b5408a0cb89413\u003c/td\u003e\n      \u003ctd\u003e90000\u003c/td\u003e\n      \u003ctd\u003e71214529679\u003c/td\u003e\n      \u003ctd\u003e21000\u003c/td\u003e\n      \u003ctd\u003e\\x538e1664c12c55287c98dc5dd248f60c642cbbbd7a18...\u003c/td\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e4\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e\\x33a3f479f6c3e7f91128348490d1f7e8d2a0fab5\u003c/td\u003e\n      \u003ctd\u003eNone\u003c/td\u003e\n      \u003ctd\u003e5000000000000000000\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\n### Saving to CSV\n\nTo save a query to a CSV, we can take advantage of the `to_csv` method on our `df`\n\n```python\ncreated_query.df.to_csv('my_test_data.csv')\n```\n\n## Roadmap\n\n- [ ] Cleanup punding TODO comments\n- [ ] Add support for embedding Dune graphs/ plotting w/ Dune style colors\n- [ ] Add tests (lol)\n- [ ] Add support for query updating\n- [ ] Investigate whether dashboard support makes sense?\n- [ ] Investigate whether there is a max row limit for data returned, if so, query in batches?\n- [ ] Better formatting for certain returned columns (links etc..)\n- [ ] Add Documentation (Sphinx or something else)\n\n## Notes\n\n_This project was inspired by the [itzemstar's duneanalytics repo](https://github.com/itzmestar/duneanalytics)_\n\n_README image is from the [IAN Symbols dataset](https://ian.umces.edu/media-library/symbols/)_\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frysuds%2Fdunebuggy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frysuds%2Fdunebuggy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frysuds%2Fdunebuggy/lists"}