{"id":13697522,"url":"https://github.com/mailgun/kafka-pixy","last_synced_at":"2025-05-15T17:03:12.145Z","repository":{"id":27843788,"uuid":"31333979","full_name":"mailgun/kafka-pixy","owner":"mailgun","description":"gRPC/REST proxy for Kafka","archived":false,"fork":false,"pushed_at":"2024-04-23T15:06:40.000Z","size":6071,"stargazers_count":777,"open_issues_count":17,"forks_count":117,"subscribers_count":83,"default_branch":"master","last_synced_at":"2025-04-07T21:15:44.242Z","etag":null,"topics":["grpc","http","json","kafka","proxy","rest"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mailgun.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2015-02-25T20:22:28.000Z","updated_at":"2025-03-27T14:11:57.000Z","dependencies_parsed_at":"2024-04-22T20:54:40.881Z","dependency_job_id":"1f347087-5f3d-4617-8f9d-aa414f91285d","html_url":"https://github.com/mailgun/kafka-pixy","commit_stats":{"total_commits":479,"total_committers":18,"mean_commits":26.61111111111111,"dds":0.09603340292275575,"last_synced_commit":"46483ae7d9d5a86d53257f4fa30dd660f5cb7886"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailgun%2Fkafka-pixy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailgun%2Fkafka-pixy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailgun%2Fkafka-pixy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailgun%2Fkafka-pixy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mailgun","download_url":"https://codeload.github.com/mailgun/kafka-pixy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254384937,"owners_count":22062421,"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":["grpc","http","json","kafka","proxy","rest"],"created_at":"2024-08-02T18:00:59.731Z","updated_at":"2025-05-15T17:03:12.124Z","avatar_url":"https://github.com/mailgun.png","language":"Go","funding_links":[],"categories":["Libraries","Tools","Operations","Go"],"sub_categories":["Kafka","Other","Tools"],"readme":"# Kafka-Pixy (gRPC/REST Proxy for Kafka)\n\n[![Build Status](https://travis-ci.org/mailgun/kafka-pixy.svg?branch=master)](https://travis-ci.org/mailgun/kafka-pixy)\n[![Go Report Card](https://goreportcard.com/badge/github.com/mailgun/kafka-pixy)](https://goreportcard.com/report/github.com/mailgun/kafka-pixy)\n[![Coverage Status](https://coveralls.io/repos/mailgun/kafka-pixy/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/mailgun/kafka-pixy?branch=master)\n[![Docker Pulls](https://img.shields.io/docker/pulls/mailgun/kafka-pixy.svg)](https://hub.docker.com/r/mailgun/kafka-pixy/)\n\nKafka-Pixy is a dual API (gRPC and REST) proxy for [Kafka](http://kafka.apache.org/documentation.html)\nwith automatic consumer group control. It is designed to hide the\ncomplexity of the Kafka client protocol and provide a stupid simple\nAPI that is trivial to implement in any language.\n\nKafka-Pixy is tested against Kafka versions **1.1.1** and **2.3.0**, but is \nlikely to work with any version starting from **0.8.2.2**. It uses\nthe Kafka [Offset Commit/Fetch API](https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-OffsetCommit/FetchAPI)\nto keep track of consumer offsets. However [Group Membership API](https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-GroupMembershipAPI)\nis not yet implemented, therefore it needs to talk to Zookeeper directly to\nmanage consumer group membership.\n\n**Warning**: Kafka-Pixy does not support wildcard subscriptions and therefore\ncannot coexist in a consumer group with clients using them. It should be\npossible to use other clients in the same consumer group as kafka-pixy instance\nif they subscribe to topics by their full names, but that **has never been\ntested** so do that at your own risk.\n\nIf you are anxious to get started then [install](howto-install.md) Kafka-Pixy\nand proceed with a quick start guide for your weapon of choice:\n[Curl](quick-start-curl.md), [Python](quick-start-python.md), or [Golang](quick-start-golang.md).\nIf you want to use some other language, then you still can use either of the\nguides for inspiration, but you would need to generate gRPC client stubs\nfrom [kafkapixy.proto](kafkapixy.proto) yourself (please refer to [gRPC documentation](http://www.grpc.io/docs/)\nfor details).\n\n#### Key Features:\n\n- **Automatic Consumer Group Management**: Unlike in\n  [Kafka REST Proxy](https://docs.confluent.io/current/kafka-rest/docs/index.html)\n  by [Confluent](https://www.confluent.io/) clients do not need to explicitly\n  create a consumer instance. When Kafka-Pixy gets a consume request for a\n  group-topic pair for the first time, it automatically joins the group and\n  subscribes to the topic. When requests stop coming for longer than the\n  [subscription timeout](https://www.confluent.io/) it cancels the subscription;\n- **At Least Once Guarantee**: The main feature of Kafka-Pixy is that\n  it guarantees at-least-once message delivery. The guarantee is\n  achieved via combination of synchronous production and explicit\n  acknowledgement of consumed messages;\n- **Dual API**: Kafka-Pixy provides two types of API:\n  - [gRPC](http://www.grpc.io/docs/guides/)\n    ([Protocol Buffers](https://developers.google.com/protocol-buffers/docs/overview)\n    over [HTTP/2](https://http2.github.io/faq/)) recommended to\n    produce/consume messages;\n  - REST (JSON over HTTP) intended for testing and operations purposes,\n    although you can use it to produce/consume messages too;\n- **Multi-Cluster Support**: One Kafka-Pixy instance can proxy to\n  several Kafka clusters. You just need to define them in the [config\n  file](https://github.com/mailgun/kafka-pixy/blob/master/default.yaml)\n  and then address clusters by name given in the config file in your\n  API requests.\n- **Aggregation**: Kafka works best when messages are read/written in\n  batches, but from an application's standpoint it is easier to deal with\n  individual message read/writes. Kafka-Pixy provides a message based API\n  to clients, but internally it aggregates requests and sends them to\n  Kafka in batches.\n- **Locality**: Kafka-Pixy is intended to run on the same host as the\n  applications using it. Remember that it only provides a message based\n  API - no batching, therefore using it over network is suboptimal.\n\n## gRPC API\n\n[gRPC](http://www.grpc.io/docs/guides/) is an open source framework\nthat is using [Protocol Buffers](https://developers.google.com/protocol-buffers/docs/overview)\nas interface definition language and [HTTP/2](https://http2.github.io/faq/)\nas transport protocol. Kafka-Pixy API is defined in\n[kafkapixy.proto](https://github.com/mailgun/kafka-pixy/blob/master/kafkapixy.proto).\nClient stubs for [Golang](https://github.com/mailgun/kafka-pixy/blob/master/gen/golang)\nand [Python](https://github.com/mailgun/kafka-pixy/tree/master/gen/python)\nare generated and provided in this repository, but you can easily\ngenerate stubs for a bunch of other languages. Please refer to the gRPC\n[documentation](http://www.grpc.io/docs/) for information on the\nlanguage of your choice.\n\n## REST API\n\n**It is highly recommended to use the gRPC API for production/consumption.\nThe HTTP API is only provided for quick tests and operational purposes.**\n\nEach API endpoint has two variants which differ by `/clusters/\u003ccluster\u003e`\nprefix. The one with the proxy prefix is to be used when multiple\nclusters are configured. The one without the prefix operates on the\ndefault cluster (the one that is mentioned first in the YAML\nconfiguration file).\n\n### Produce\n\n```\nPOST /topics/\u003ctopic\u003e/messages\nPOST /clusters/\u003ccluster\u003e/topics/\u003ctopic\u003e/messages\n```\n\nWrites a message to a topic on a particular cluster. If the request content\ntype is either `text/plain` or `application/json` then a message should be sent as\nthe body of a request. If content type is `x-www-form-urlencoded` then a\nmessage should be passed as the `msg` form parameter.\n\nIf Kafka-Pixy is configured to use a version of the Kafka protocol (via the\n`kafka.version` proxy setting) that is 0.11.0.0 or later, it is also possible to\nadd [record\nheaders](https://cwiki.apache.org/confluence/display/KAFKA/KIP-82+-+Add+Record+Headers)\nto a message by adding HTTP headers to your message. Any HTTP header with the\nprefix \"X-Kafka-\" will have that prefix stripped and the header will be used as\na record header. Since the values of Kafka headers can be arbitrary byte\nstrings, the value of the HTTP header must be Base 64-encoded.\n\n Parameter | Opt | Description\n-----------|-----|------------------------------------------------------\n cluster   | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n topic     |     | The name of a topic to produce to\n key       | yes | A string whose hash is used to determine a partition to produce to. By default a random partition is selected.\n msg       |  *  | Used only if the request content type is `x-www-form-urlencoded`. In other cases the request body is the message.\n sync      | yes | A flag (value is ignored) that makes Kafka-Pixy wait for all ISR to confirm write before sending a response back. By default a response is sent immediatelly after the request is received.\n\nBy default the message is written to Kafka asynchronously, that is the\nHTTP request completes as soon as Kafka-Pixy reads the request from the\nwire, and production to Kafka is performed in the background. Therefore\nit is not guaranteed that the message will ever get into Kafka.\n\nIf you need a guarantee that a message is written to Kafka, then pass the **sync**\nflag with your request. In that case when Kafka-Pixy returns a response is\ngoverned by `producer.required_acks` parameter in the YAML config. It can be one\nof:\n * **no_response**: the response is returned as soon as a produce request is\n   delivered to a partition leader Kafka broker (no disk writes performed yet).\n * **wait_for_local**: the response is returned as soon as data is written to\n   the disk by a partition leader Kafka broker.\n * **wait_for_all**: the response is returned after all in-sync replicas have\n   data committed to disk.\n\nE.g. if a Kafka-Pixy process has been started with the `--tcpAddr=0.0.0.0:8080`\nargument, then you can test it using **curl** as follows:\n\n```\ncurl -X POST localhost:8080/topics/foo/messages?key=bar\u0026sync \\\n  -H 'Content-Type: text/plain' \\\n  -d 'Good news everyone!'\n```\n\nIf the message is submitted asynchronously then the response will be an\nempty json object `{}`.\n\nIf the message is submitted synchronously then in case of success (HTTP\nstatus **200**) the response will be like:\n\n```\n{\n  \"partition\": \u003cpartition number\u003e,\n  \"offset\": \u003cmessage offset\u003e\n}\n```\n\nIn case of failure (HTTP statuses **404** and **500**) the response\nwill be:\n\n```\n{\n  \"error\": \u003chuman readable explanation\u003e\n}\n```\n\n### Consume\n\n```\nGET /topics/\u003ctopic\u003e/messages\nGET /clusters/\u003ccluster\u003e/topics/\u003ctopic\u003e/messages\n```\n\nConsumes a message from a topic of a particular cluster as a member of\na particular consumer group. A message previously consumed from the same\ntopic can be optionally acknowledged.\n\n Parameter    | Opt | Description\n--------------|-----|------------------------------------------------------\n cluster      | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n topic        |     | The name of a topic to consume from.\n group        |     | The name of a consumer group.\n noAck        | yes | A flag (value is ignored) that no message should be acknowledged. For default behaviour read below.\n ackPartition | yes | A partition number that the acknowledged message was consumed from. For default behaviour read below.\n ackOffset    | yes | An offset of the acknowledged message. For default behaviour read below.\n\nIf **noAck** is defined in a request then no message is acknowledged\nby the request. If a request defines both **ackPartition** and\n**ackOffset** parameters then a message previously consumed from the\nsame topic from the specified partition with the specified offset is\nacknowledged by the request. If none of the ack related parameters is\nspecified then the request will acknowledge the message consumed in this\nrequests if any. It is called `auto-ack` mode.\n\nWhen a message is consumed as a member of a consume group for the first\ntime, Kafka-Pixy joins the consumer group and subscribes to the topic.\nAll Kafka-Pixy instances that are currently members of that group and\nsubscribed to that topic distribute partitions between themselves, so\nthat each Kafka-Pixy instance gets a subset of partitions for exclusive\nconsumption (Read more about Kafka consumer groups\n[here](http://kafka.apache.org/documentation.html#intro_consumers)).\n\nIf a Kafka-Pixy instance has not received consume requests for a topic for the duration of the\n[subscription timeout](https://github.com/mailgun/kafka-pixy/blob/master/default.yaml#L139),\nthen it unsubscribes from the topic, and the topic partitions are\nredistributed among Kafka-Pixy instances that are still consuming from it.\n\nIf there are no unread messages in the topic the request will block\nwaiting for the duration of the [long polling timeout](https://github.com/mailgun/kafka-pixy/blob/master/default.yaml#L109).\nIf there are no messages produced during this long poll waiting then the request\nwill return **408 Request Timeout** error, otherwise the response will\nbe a JSON document of the following structure:\n\n```\n{\n  \"key\": \u003cbase64 encoded key\u003e,\n  \"value\": \u003cbase64 encoded message body\u003e,\n  \"partition\": \u003cpartition number\u003e,\n  \"offset\": \u003cmessage offset\u003e,\n  \"headers\": [\n    {\n      \"key\": \u003cstring header key\u003e,\n      \"value\": \u003cbase64-encoded header value\u003e\n    }\n  ]\n}\n```\ne.g.:\n```json\n{\n  \"key\": \"0JzQsNGA0YPRgdGP\",\n  \"value\": \"0JzQvtGPINC70Y7QsdC40LzQsNGPINC00L7Rh9C10L3RjNC60LA=\",\n  \"partition\": 0,\n  \"offset\": 13,\n  \"headers\": [\n    {\n      \"key\": \"foo\",\n      \"value\": \"YmFy\"\n    }\n  ]\n}\n```\n\nNote that headers are only supported if the Kafka protocol version (set via the\n`kafka.version` configuration flag) is set to 0.11.0.0 or later.\n\n### Acknowledge\n\n```\nPOST /topics/\u003ctopic\u003e/acks\nPOST /clusters/\u003ccluster\u003e/topics/\u003ctopic\u003e/acks\n```\n\nAcknowledges a previously consumed message.\n\n Parameter | Opt | Description\n-----------|-----|------------------------------------------------------\n cluster   | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n topic     |     | The name of a topic to produce to.\n group     |     | The name of a consumer group.\n partition |     | A partition number that the acknowledged message was consumed from.\n offset    |     | An offset of the acknowledged message.\n\n### Get Offsets\n\n```\nGET /topics/\u003ctopic\u003e/offsets\nGET /clusters/\u003ccluster\u003e/topics/\u003ctopic\u003e/offsets\n```\n\nReturns offset information for all partitions of the specified **topic**\nincluding the next offset to be consumed by the specified consumer group. The\nstructure of the returned JSON document is as follows:\n\n Parameter | Opt | Description\n-----------|-----|------------------------------------------------------\n cluster   | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n topic     |     | The name of a topic to produce to.\n group     |     | The name of a consumer group.\n\n```\n[\n  {\n    \"partition\": \u003cpartition id\u003e,\n    \"begin\": \u003coldest offset\u003e,\n    \"end\": \u003cnewest offset\u003e,\n    \"count\": \u003cthe number of messages in the topic, equals to `end` - `begin`\u003e,\n    \"offset\": \u003cnext offset to be consumed by this consumer group\u003e,\n    \"lag\": \u003cequals to `end` - `offset`\u003e,\n    \"metadata\": \u003carbitrary string committed with the offset, not used by Kafka-Pixy. It is omitted if empty\u003e\n  },\n  ...\n]\n```\n\n### Set Offsets\n\n```\nPOST /topics/\u003ctopic\u003e/offsets\nPOST /clusters/\u003ccluster\u003e/topics/\u003ctopic\u003e/offsets\n```\n\nSets offsets to be consumed from the specified topic by a particular consumer\ngroup. The request content should be a list of JSON objects, where each object\ndefines an offset to be set for a particular partition:\n\n Parameter | Opt | Description\n-----------|-----|------------------------------------------------------\n cluster   | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n topic     |     | The name of a topic to produce to.\n group     |     | The name of a consumer group.\n\n```\n[\n  {\n    \"partition\": \u003cpartition id\u003e,\n    \"offset\": \u003cnext offset to be consumed by this consumer group\u003e,\n    \"metadata\": \u003carbitrary string\u003e\n  },\n  ...\n]\n```\n\nNote that consumption by all consumer group members should cease before this\ncall can be executed. That is necessary because while consuming, Kafka-Pixy\nconstantly updates partition offsets, and it does not expect them to be updated\nby somebody else. So it only reads them on group initialization, that happens\nwhen a consumer group request comes after 20 seconds or more of the consumer\ngroup inactivity on all Kafka-Pixy instances working with the Kafka cluster.\n\n### List Consumers\n\n```\nGET /topics/\u003ctopic\u003e/consumers\nGET /clusters/\u003ccluster\u003e/topics/\u003ctopic\u003e/consumers\n```\n\nReturns a list of consumers that are subscribed to a topic.\n\n Parameter | Opt | Description\n-----------|-----|------------------------------------------------\n cluster   | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n topic     |     | The name of a topic to produce to.\n group     | yes | The name of a consumer group. By default returns data for all known consumer groups subscribed to the topic.\n\ne.g.:\n\n```\ncurl -G localhost:19092/topic/some_queue/consumers\n```\n\nyields:\n\n```\n{\n  \"integrations\": {\n    \"pixy_jobs1_62065_2015-09-24T22:21:05Z\": [0,1,2,3],\n    \"pixy_jobs2_18075_2015-09-24T22:21:28Z\": [4,5,6],\n    \"pixy_jobs3_336_2015-09-24T22:21:51Z\": [7,8,9]\n  },\n  \"logstash-customer\": {\n    \"logstash-customer_logs01-1443116116450-7f54d246-0\": [0,1,2],\n    \"logstash-customer_logs01-1443116116450-7f54d246-1\": [3,4,5],\n    \"logstash-customer_logs01-1443116116450-7f54d246-2\": [6,7],\n    \"logstash-customer_logs01-1443116116450-7f54d246-3\": [8,9]\n  },\n  \"logstash-reputation4\": {\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-0\": [0],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-1\": [1],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-10\": [2],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-11\": [3],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-12\": [4],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-13\": [5],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-14\": [6],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-15\": [7],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-2\": [8],\n    \"logstash-reputation4_logs16-1443178335419-c08d8ab6-3\": [9]\n  },\n  \"test\": {\n    \"pixy_core1_47288_2015-09-24T22:15:36Z\": [0,1,2,3,4],\n    \"pixy_in7_102745_2015-09-24T22:24:14Z\": [5,6,7,8,9]\n  }\n}\n```\n\n### List Topics\n\n```\nGET /topics\nGET /clusters/\u003ccluster\u003e/topics\n```\n\nReturns a list of topics optionally with detailed configuration and partitions.\n\n Parameter      | Opt | Description\n----------------|-----|------------------------------------------------\n cluster        | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n withPartitions | yes | Whether a list of partitions should be returned for every topic.\n withConfig     | yes | Whether configuration should be returned for every topic.\n\n### Get Topic Config\n\n```\nGET /topics/\u003ctopic\u003e\nGET /clusters/\u003ccluster\u003e/topics/\u003ctopic\u003e\n```\n\nReturns topic configuration optionally with a list of partitions.\n\n Parameter      | Opt | Description\n----------------|-----|------------------------------------------------\n cluster        | yes | The name of a cluster to operate on. By default the cluster mentioned first in the `proxies` section of the config file is used.\n withPartitions | yes | Whether a list of partitions should be returned.\n\n## Configuration\n\nKafka-Pixy is designed to be very simple to run. It consists of a single\nexecutable that can be started just by passing a bunch of command line\nparameters to it - no configuration file needed.\n\nHowever if you do need to fine-tune Kafka-Pixy for your use case, you can\nprovide a YAML configuration file. Default configuration file\n[default.yaml](https://github.com/mailgun/kafka-pixy/blob/master/default.yaml)\nis shipped in the release archive. In your configuration file you can specify\nonly parameters that you want to change, other options take their default\nvalues. If some option is both specified in the configuration file and provided\nas a command line argument, then the command line argument wins.\n\nCommand line parameters that Kafka-Pixy accepts are listed below:\n\n Parameter      | Description\n----------------|-------------------------------------------------------------------\n config         | Path to a YAML configuration file.\n kafkaPeers     | Comma separated list of Kafka brokers. Note that these are just seed brokers. The other brokers are discovered automatically. (Default **localhost:9092**)\n zookeeperPeers | Comma separated list of ZooKeeper nodes followed by optional chroot. (Default **localhost:2181**)\n grpcAddr       | TCP address that the gRPC API should listen on. (Default **0.0.0.0:19091**)\n tcpAddr        | TCP address that the HTTP API should listen on. (Default **0.0.0.0:19092**)\n unixAddr       | Unix Domain Socket that the HTTP API should listen on. If not specified then the service will not listen on a Unix Domain Socket.\n pidFile        | Name of a pid file to create. If not specified then a pid file is not created.\n\nYou can run `kafka-pixy -help` to make it list all available command line\nparameters.\n\n### Security\n\nSSL/TLS can be configured on both the gRPC and HTTP servers by\nspecifying a certificate and key file in the configuration. Both files\nmust be specified in order to run with security enabled.\n\nIf configured, both the gRPC and HTTP servers will run with TLS enabled.\n\nAdditionally TLS may be configured for the Kafka cluster by enabling `tls` in\nthe `kafka` section of the configuration YAML (along with any required\ncertificates). Details can be found in the default YAML file (`default.yaml`).\n\n## License\n\nKafka-Pixy is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmailgun%2Fkafka-pixy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmailgun%2Fkafka-pixy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmailgun%2Fkafka-pixy/lists"}