{"id":37070101,"url":"https://github.com/som-energia/redasher","last_synced_at":"2026-01-14T08:04:29.904Z","repository":{"id":57460591,"uuid":"353357238","full_name":"Som-Energia/redasher","owner":"Som-Energia","description":"Tool to manage workflow from redash data to files that can be managed by git","archived":false,"fork":false,"pushed_at":"2022-12-19T07:29:45.000Z","size":113,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-10-31T15:34:57.884Z","etag":null,"topics":["continuous-delivery","git","redash","serialization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Som-Energia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","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":"2021-03-31T12:57:20.000Z","updated_at":"2021-05-03T08:25:07.000Z","dependencies_parsed_at":"2023-01-29T20:46:16.858Z","dependency_job_id":null,"html_url":"https://github.com/Som-Energia/redasher","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/Som-Energia/redasher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Som-Energia%2Fredasher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Som-Energia%2Fredasher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Som-Energia%2Fredasher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Som-Energia%2Fredasher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Som-Energia","download_url":"https://codeload.github.com/Som-Energia/redasher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Som-Energia%2Fredasher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413527,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["continuous-delivery","git","redash","serialization"],"created_at":"2026-01-14T08:04:29.350Z","updated_at":"2026-01-14T08:04:29.895Z","avatar_url":"https://github.com/Som-Energia.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Redasher\n\nThis tool manages Redash objects as files,\nenabling version control and having development environments.\n\nThe purpose of this tool is to serialize [Redash](http://redash.io) objects\n(dashboards, queries, visualizations...)\ninto the filesystem so that they can be maintained using tools like Git.\nYou might use that to keep track of the changes with tools like git, or\nyou can even modify those objects with a text editor and update your instance.\nBy tracking a second Redash instance you can use this tool to syncronize objects among them.\nThis is useful, for example, to make and test changes in a development  environment\nand eventually apply those changes into a production one.\n\n\n## Usage\n\nLets start by defining our production server, by setting up the base url\nand the API key of the user we will use to interact.\n\n```bash\nredasher setup prod http://redash.mycompany.com:8012 a2xcvvr23werwcdvhtsdfa23424df\n```\n\nA configuration file in `~/.config/redash_gitstudio/config.yaml` will be created.\n\nThen lets download all the objects from `prod`\n\n```bash\nredasher checkout prod\n```\n\nThis will create the following directory structure in the current directory:\n\n```\nmaps/\nmaps/prod.yaml # mappings from local files to object ids in `prod` server\ndashboards/\u003cname\u003e/metadata.yaml # dashboards metadata\ndashboards/\u003cname\u003e/widgets/\u003cname\u003e.yaml # dashboard widgets\nqueries/\u003cname\u003e/query.sql # The query string file\nqueries/\u003cname\u003e/metadata.yaml # The rest of the metadata\nqueries/\u003cname\u003e/visualizations/\u003cname\u003e.yaml # query visualizatons\n```\n\nYou can put those files under the wing of a version control system like git,\nand keep track of your object changes in redash\nby running checkout and committing resulting files at any step.\n\nYou can also modify the content of those files\nand then upload them back to the server:\n\n```bash\nredasher upload prod dashboard/my-dashboard\n```\n\nAnother common workflow is working with an internal server\nto develop without disturbing production users and\nsynchronize when you are done with the changes.\n\nFor that you must define a new server:\n\n```bash\nredasher setup dev http://localhost:8080 sdfa23424dfa2xcvvr23werwcdvht\n```\n\nRedash datasource objects are considered readonly.\nIf you want to synchronize two servers, first you must\nmanually bind the datasource file object\nchecked out from the first server, to the\nid of an equivalent datasource you created in the second server.\n\n```bash\nredasher bind dev datasource/my-database.yaml 3\n```\n\nThen you can upload the objects to create them.\n\n```bash\nredasher upload dev dashboard/my-dashboard\n```\n\nFrom now on, succesive file uploads to the new server\nwill be updates on the same objects.\n\n\n## Understanding maps/\n\nThe directory `maps` contains a file for each server.\nSuch files relate server object id's to file objects.\nSuch a relation is set the first time you checkout an object from a server,\nor the first time you upload an object into a server and thus creating a new object.\n\nWhen you upload a file object to a server.\nIf the file object already has a bound id on the server,\nthe object is updated.\nOtherwise a new object is created.\n\nLikewise, whenever you checkout an object from a server,\nif the map exists, the content will be dump in the same file.\nIf not, a proper file name will be generated based on the slug\nof the current object name.\nIf the name already exists a serial number is added.\n\nYou can also set a server mapping by hand with the `bind` subcommand\nlike in the previous example with the datasource.\n\n\n\n## Design\n\n### Decision Log\n\n- Sluggified names are used as object file names since they are more easily spotted than a hash\n- Sluggified names are keept even if the name of the object changes later\n- Non composition relations are mapped with an attribute refering the object path names instead of ids.\n  - Numeric id's from server are instance dependant\n  - A common numeric serialization id would solve that but it would be harder to search and replace\n- Composition relations (dashboard -\u003e widgets, query -\u003e visualizations) are\n  mapped as directory hierarchy. This eases copying objects as a whole.\n- Ids in each redash instance are different so \"instance id\" to \"object file\" maps should be tracked per instance\n- While production object mapping should be part of a shared repository,\n  private development servers might have sense for a single developer.\n  So, file-id maps should be in different files for each file so you can\n  decide which servers are shared in a repository.\n- Permanent mapping from id and a file object should be stablished:\n  - The first time you download a given server object with no previous bound in that server\n  - The first time you upload a file object to a given server with no previous bound in that server\n- Successive uploads and downloads should keep that binding\n  - Uploading a file object to a server where it has a bound, should update the object instead of creating it\n  - Downloading an object from a server having already a bound to a file object, overwrites the same file object\n- Data sources are mapped as well but not updated on upload, since they might point to different database configurations depending on the instance.\n  - Thus, before uploading objects refering to a datasource into a new instance,\n    it has to be created in the instance and bound using the bind command before uploading.\n- Server configuration is not to be committed, and apikey should be kept private,\n  thus it has been separated from the server id map into a user configuration file.\n- Users might be different in production and testing, a dashboard could\n  be created using a different user. \n  Thus, creation and modification users are not kept\n- Object creation and modification dates are not to be kept, or do they? (they might be used to compare update times and detecting overwritten changes)\n- Cascading uploads\n  - Uploading a dashboard uploads all its widgets\n  - Uploading a widget uploads its dashboard and its visualization\n  - Uploading a visualization uploads its query\n  - Uploading a query uploads its datasource, its visualizations and any param query\n\n### TODO\n\n- Partial checkouts\n- Alerts and destinations\n- Groups\n- Detecting overwritting changes on upload\n- git ops executed automatically\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsom-energia%2Fredasher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsom-energia%2Fredasher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsom-energia%2Fredasher/lists"}