{"id":46774394,"url":"https://github.com/protoconf/protoconf","last_synced_at":"2026-03-09T23:42:02.421Z","repository":{"id":37068149,"uuid":"225382553","full_name":"protoconf/protoconf","owner":"protoconf","description":"Configuration as Code framework based on protobuf and Starlark","archived":false,"fork":false,"pushed_at":"2026-02-27T09:48:07.000Z","size":10001,"stargazers_count":190,"open_issues_count":27,"forks_count":16,"subscribers_count":6,"default_branch":"main","last_synced_at":"2026-02-27T15:09:23.055Z","etag":null,"topics":["configuration-as-code","configuration-management","gitops","protobuf","starlark"],"latest_commit_sha":null,"homepage":"https://www.protoconf.dev","language":"Go","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/protoconf.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-12-02T13:33:43.000Z","updated_at":"2026-02-25T01:01:33.000Z","dependencies_parsed_at":"2023-02-15T19:45:22.003Z","dependency_job_id":"842ad6a0-5e8a-4784-b6d6-96a4801be6d0","html_url":"https://github.com/protoconf/protoconf","commit_stats":null,"previous_names":[],"tags_count":56,"template":false,"template_full_name":null,"purl":"pkg:github/protoconf/protoconf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoconf%2Fprotoconf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoconf%2Fprotoconf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoconf%2Fprotoconf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoconf%2Fprotoconf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/protoconf","download_url":"https://codeload.github.com/protoconf/protoconf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protoconf%2Fprotoconf/sbom","scorecard":{"id":747243,"data":{"date":"2025-08-11","repo":{"name":"github.com/protoconf/protoconf","commit":"6d2f931a1a2f428aa151dfe49d4dcd6c940cca71"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":4,"reason":"Found 4/9 approved changesets -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/go.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:9","Warn: topLevel 'packages' permission set to 'write': .github/workflows/release.yml:10","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/go.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/go.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/go.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/go.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/go.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/protoconf/protoconf/release.yml/main?enable=pin","Info:   0 out of  10 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:13"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.2.0-alpha2 not signed: https://api.github.com/repos/protoconf/protoconf/releases/195785637","Warn: release artifact v0.2.0-alpha1 not signed: https://api.github.com/repos/protoconf/protoconf/releases/155998749","Warn: release artifact v0.1.7 not signed: https://api.github.com/repos/protoconf/protoconf/releases/103559792","Warn: release artifact v0.1.6 not signed: https://api.github.com/repos/protoconf/protoconf/releases/69371354","Warn: release artifact v0.1.6-rc1 not signed: https://api.github.com/repos/protoconf/protoconf/releases/63464183","Warn: release artifact v0.2.0-alpha2 does not have provenance: https://api.github.com/repos/protoconf/protoconf/releases/195785637","Warn: release artifact v0.2.0-alpha1 does not have provenance: https://api.github.com/repos/protoconf/protoconf/releases/155998749","Warn: release artifact v0.1.7 does not have provenance: https://api.github.com/repos/protoconf/protoconf/releases/103559792","Warn: release artifact v0.1.6 does not have provenance: https://api.github.com/repos/protoconf/protoconf/releases/69371354","Warn: release artifact v0.1.6-rc1 does not have provenance: https://api.github.com/repos/protoconf/protoconf/releases/63464183"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 1 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"16 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2017-87","Warn: Project is vulnerable to: GHSA-735f-pc8j-v9w8","Warn: Project is vulnerable to: GHSA-496j-2rq6-j6cc","Warn: Project is vulnerable to: GO-2022-0635","Warn: Project is vulnerable to: GO-2022-0646","Warn: Project is vulnerable to: GO-2025-3754 / GHSA-2x5j-vhc8-9cwm","Warn: Project is vulnerable to: GO-2025-3367 / GHSA-r9px-m959-cxf4","Warn: Project is vulnerable to: GO-2025-3368 / GHSA-v725-9546-7q7m","Warn: Project is vulnerable to: GO-2024-2948 / GHSA-xfhp-jf8p-mh5w","Warn: Project is vulnerable to: GO-2024-3321 / GHSA-v778-237x-gjrc","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2025-3488 / GHSA-6v2p-p543-phr9","Warn: Project is vulnerable to: GO-2024-2978 / GHSA-xr7q-jx4m-x55m"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T19:12:16.435Z","repository_id":37068149,"created_at":"2025-08-22T19:12:16.435Z","updated_at":"2025-08-22T19:12:16.435Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30316774,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T20:05:46.299Z","status":"ssl_error","status_checked_at":"2026-03-09T19:57:04.425Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["configuration-as-code","configuration-management","gitops","protobuf","starlark"],"created_at":"2026-03-09T23:42:02.292Z","updated_at":"2026-03-09T23:42:02.405Z","avatar_url":"https://github.com/protoconf.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\u003ch1\u003eProtoconf\u003c/h1\u003e\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg alt=\"logo\" src=\"https://protoconf.github.io/protoconf/assets/protoconf_new.svg\" height=\"128\"\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n\u003ch4\u003ecodify configuration, instant delivery\u003c/h4\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch3\u003e\n    \u003ca href=\"#quick-start\"\u003e\n      Quick start\n    \u003c/a\u003e\n    \u003cspan\u003e | \u003c/span\u003e\n    \u003ca href=\"#production-setup\"\u003e\n      Production setup\n    \u003c/a\u003e\n    \u003cspan\u003e | \u003c/span\u003e\n    \u003ca href=\"#build-from-source\"\u003e\n      Build from source\n    \u003c/a\u003e\n    \u003cspan\u003e | \u003c/span\u003e\n    \u003ca href=\"https://protoconf.github.io/protoconf\"\u003e\n      Documentation\n    \u003c/a\u003e\n    \u003cspan\u003e | \u003c/span\u003e\n    \u003ca href=\"https://lior2b.github.io/temp/\"\u003e\n      Web IDE\n    \u003c/a\u003e\n  \u003c/h3\u003e\n\u003c/div\u003e\n\n![Test](https://github.com/protoconf/protoconf/workflows/Check/badge.svg)\n![Release](https://github.com/protoconf/protoconf/workflows/goreleaser/badge.svg)\n\n\n## Introduction\n\nModern services are comprised of many dynamic variables, that need to be changed regularly. Today, the process is unstructured and error prone. From ML model variables, kill switches, gradual rollout configuration, A/B experiment configuration and more - developers want their code to allow to be configured to the finer details.\n\n**Protoconf is a modern approach to software configuration**, inspired by [Facebook's Configerator](https://research.fb.com/publications/holistic-configuration-management-at-facebook/).\n\nUsing Protoconf enables:\n\n- **Code review for configuration changes**\n  Enables the battle tested flow of pull-request \u0026 code-review. Configuration auditing out of the box (who did what, when?). The repository is the source of truth for the configuration deployed to production.\n- **No service restart required to pick up changes**\n  Instant delivery of configuration updates. Encourages writing software that doesn't know downtime.\n- **Clear representation of complex configuration**\n  Write configuration in Starlark (a Python dialect), no more copying \u0026 pasting from huge JSON files.\n- **Automated validation**\n  Config follows a fully-typed (Protobuf) schema. This allows writing validation code in Starlark, to verify your configuration before it is committed.\n\n#### Configuration update flow\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://lior2b.github.io/temp/protoconf_flow.png\"\u003e\n\u003c/div\u003e\n\n#### How this looks from the service's eyes\n\nThis is roughly how configuration is consumed by a service. This paradigm encourages you to write software that can reconfigure itself in runtime rather than require a restart:\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://lior2b.github.io/temp/protoconf_api.png\" width=\"400\"\u003e\n\u003c/div\u003e\n\nAs Protoconf uses Protobuf and gRPC, it supports delivering configuration to [all major languages](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md). See also: [Protobuf overview](https://developers.google.com/protocol-buffers/docs/overview).\n\n## Quick start\n\nStep by step instructions to start developing with Protoconf, with an example from an imaginary Python web crawler service. See full example under `examples/`.\n\n1. Install the `protoconf` binary (see [build from source](#build-from-source))\n\n2. Write a Protobuf schema under `protoconf/src/`(syntax guide https://developers.google.com/protocol-buffers/docs/proto3)\n\n   1. For example: `protoconf/src/crawler/crawler.proto`\n\n   ```protobuf\n   syntax = \"proto3\";\n\n   message Crawler {\n     string user_agent = 1;\n     int32 http_timeout = 2;\n     bool follow_redirects = 3;\n   }\n\n   message CrawlerService {\n     repeated Crawler crawlers = 1;\n     enum AdminPermission {\n       READ_WRITE = 0;\n       GOD_MODE = 1;\n     }\n     map\u003cstring, AdminPermission\u003e admins = 2;\n     int32 log_level = 3;\n   }\n   ```\n\n   2. Pro tip: adding fields to an existing schema? Don't worry, Protobuf is backward and forward compatible (https://en.wikipedia.org/wiki/Protocol_Buffers)\n\n3. Write validators _(optional)_\n\n   1. Write a Starlark file alongside the `.proto` file, with a `.proto-validator` suffix\n   2. For example: `protoconf/src/crawler/crawler.proto-validator`\n\n   ```python\n   load(\"crawler.proto\", \"Crawler\", \"CrawlerService\")\n\n   def test_crawlers_not_empty(cs):\n       if len(cs.crawlers) \u003c 1:\n           fail(\"Crawlers can't be empty\")\n\n   add_validator(CrawlerService, test_crawlers_not_empty)\n\n   def test_http_timeout(c):\n       MIN_TIMEOUT = 10\n       if c.http_timeout \u003c MIN_TIMEOUT:\n           fail(\"Crawler HTTP timeout must be at least %d, got %d\" % (MIN_TIMEOUT, c.http_timeout))\n\n   add_validator(Crawler, test_http_timeout)\n   ```\n\n4. Write a config\n\n   1. A Starlark `.pconf` file. Your code can be modular, export functions (ideally in `.pinc` files), and build a complete custom stack for your configuration needs.\n   2. For example: `protoconf/src/crawler/text_crawler.pconf`\n\n      ```python\n      load(\"crawler.proto\", \"Crawler\", \"CrawlerService\")\n\n      def default_crawler():\n          return Crawler(user_agent=\"Linux\", http_timeout=30)\n\n      def main():\n          crawlers = []\n\n          for i in range(3):\n              crawler = default_crawler()\n              crawler.http_timeout = 30 + 30*i\n                  if i == 0:\n                      crawler.follow_redirects = True\n              crawlers.append(crawler)\n\n          admins = {'superuser': CrawlerService.AdminPermission.GOD_MODE}\n          return CrawlerService(crawlers=crawlers, admins=admins, log_level=2)\n      ```\n\n   3. Compile with `protoconf compile`, this will create a materialized config file under `protoconf/materialized_configs/`\n   4. For example: `protoconf compile protoconf/ crawler/text/crawler` will create `protoconf/materialized_config/crawler/text_crawler.materialized_JSON`\n\n   ```json\n   {\n     \"protoFile\": \"crawler/crawler.proto\",\n     \"value\": {\n       \"@type\": \"https://CrawlerService\",\n       \"admins\": {\n         \"superuser\": \"GOD_MODE\"\n       },\n       \"crawlers\": [\n         {\n           \"userAgent\": \"Linux\",\n           \"httpTimeout\": 30,\n           \"followRedirects\": true\n         },\n         {\n           \"userAgent\": \"Linux\",\n           \"httpTimeout\": 60\n         },\n         {\n           \"userAgent\": \"Linux\",\n           \"httpTimeout\": 90\n         }\n       ],\n       \"logLevel\": 2\n     }\n   }\n   ```\n\n5. Run the Protoconf agent in dev mode\n   ```bash\n   protoconf agent protoconf/\n   ```\n6. Prepare your application to work with Protobuf configs coming from Protoconf\n\n   1. Compile your `.proto` schema, this will generate an object to work with.\n      For Python you can use `grpcio-tools`, for example:\n\n      ```bash\n      pip3 install grpcio-tools\n      python3 -m grpc_tools.protoc --python_out=. -I../protoconf/src ../protoconf/src/crawler/crawler.proto\n      ```\n\n      Other languages can use the `protoc` binary (https://developers.google.com/protocol-buffers/docs/tutorials).\n\n   2. Install the Protoconf Python library:\n\n   ```bash\n   pip3 install -r python/requirements.txt python/\n   ```\n\n   3. In your code, setup a connection to Protoconf and get the config. See full example under `examples/`. The code mainly consists of:\n\n   ```python\n   from protoconf import ProtoconfSync\n   from crawler.crawler_pb2 import CrawlerService\n\n   protoconf = ProtoconfSync()\n   crawler_service = protoconf.get_and_subscribe(\"crawler/text_crawler\", CrawlerService, got_config)\n   print(\"config:\", crawler_service)\n\n   def got_config(new_crawler_service):\n       print(\"got a new config:\", new_crawler_service)\n   ```\n\n7. Commit all changes under `protoconf/` (including the `.materialized_JSON` files)\n\n## Production setup\n\n1. Run your preferred key-value store (e.g. Consul)\n2. Run the Protoconf agent: `protoconf agent`\n3. Setup a commit hook in your repository server (e.g. Github) that runs `protoconf update` on changed `.materialized_JSON` files\n\n## Build from source\n\n1. Clone Protoconf: `git clone https://github.com/protoconf/protoconf.git`\n2. Build the binary: `cd protoconf \u0026\u0026 go install ./cmd/protoconf`\n3. Ensure that GOPATH/bin is in your path\n\n\n## Trying the example\n\n1. Make sure Consul is listening locally on default port (you can achieve this with `consul agent -dev`)\n2. Run the agent: `bazel run protoconf agent`\n3. Compile the Protoconf config: `bazel run protoconf compile \"$(pwd)/examples/protoconf\" crawler/text_crawler.pconf`\n4. Insert the Protoconf config to Consul: `bazel run protoconf insert \"$(pwd)/examples/protoconf\" crawler/text_crawler.materialized_JSON`\n5. Run the Go client: `bazel run //examples/grpc_clients/go_client`, the client will get the config from the agent and will listen to changes\n6. Change the config file at `examples/protoconf/src/crawler/text_crawler.pconf`\n7. Repeat steps 4 \u0026 5 to recompile and re-insert the config, observe the client got the updated config\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotoconf%2Fprotoconf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprotoconf%2Fprotoconf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotoconf%2Fprotoconf/lists"}