{ "info": { "author": "Jaumo GmbH", "author_email": "nicola.bova@jaumo.com", "bugtrack_url": null, "classifiers": [], "description": "# Avro-Preprocessor\n\n\n\n\nThis Python project provides a preprocessor for Avro resources. \n\nThe preprocessor is made up of a list of modules.\nEach module, in the specified order, performs an operation over the entire list of Avro resources. \n\nThe input is a directory tree (namespace-like) in which each file is either a `domain_message`s or a `type`.\n\nThe output is another directory tree, with the same structure as input, in which Avro resources\nunderwent the list of preprocessing operations. \n\nInput Avro resources (`domain_message` or `type`) have `exavsc` as file extension.\nOutput Avro resources have `avsc` as file extension.\n\n## Schema definition\n\nTwo different kinds of data structures are used in this project: *domain messages* and *types*.\n\n#### Domain messages\n\nDomain messages are Avro schemas that can be sent over a Kafka topic.\nIn general, multiple messages can be associated to each Kafka topic. \nDomain messages are placed in\n\n`schema/com/example/message_schema/domain//`\n\n#### Types\n\nTypes are reusable structures that can be referenced in a domain message.\nThey are placed in\n\n`schema/com/example/message_schema/type/`\n\nDomain messages *cannot* be reused (i.e. referenced by other domain messages).\n\n### Naming rules \n\n- Directory structure must match the namespaces used inside the message / type definitions\n- Records are defined in camel case\n- Properties are defined in snake case\n\n### Kafka topics and Avro subjects\n\nEach directory `` under `schema/com/example/message_schema/domain/`\nrepresents a Kafka topic. All schemas under a specific topic directory (and only them)\nwill be available to be sent on the corresponding Kafka topic, i.e. they will be registered\non the schema registry.\n\nFor subject naming we follow the guidelines defined by Confluent to \n[put several event types in the same Kafka topic](\nhttps://www.confluent.io/blog/put-several-event-types-kafka-topic/); \nin particular we use the strategy \n`io.confluent.kafka.serializers.subject.TopicRecordNameStrategy`.\n\nThis behaviour is defined in `avro_naming.py`. \n\n##### Topic name\n```\ndomain.\n```\n\n##### Avro subject names\n```\ndomain.-\n```\n\n##### Example\nFor schema directory:\n```\nschema/com/example/message_schema/domain/user/\n```\n\nTopic name:\n```\ndomain.user\n```\n\nList of Avro subjects names:\n```\ndomain.user-com.example.message_schema.domain.user.UserCreated\ndomain.user-com.example.message_schema.domain.user.UserUpdated\ndomain.user-com.example.message_schema.domain.user.UserDeleted\n```\n\n\n## List of available preprocessing modules\n\nThe following modules shoud be applied in the order shown as follows.\nHowever, they are all optional.\n\n- `DocumentationCondenser`: JSON strings don't support multi lines inside an editor. This makes\nit inconvenient to write long documentation for some fields. This module adds support for\nlists as `doc` field in Avro schemas (they will be joined in the output). \n- `NamespaceChecker`: Checks if a resource namespace corresponds to the directory tree structure.\n- `DocumentationChecker`: Checks if the documentation corresponds to specific rules:\n 1. (sub) schemas with a \"name\" property MUST have a \"doc\" property.\n 2. (sub) schemas without a \"name\" property MUST NOT have a \"doc\" property.\n 3. If two (sub) schemas have the same \"doc\", they must be identical.\n- `NamesChecker`: Checks if schema, record, or enums names are in `CamelCase` while all other\nproperties in `snake_case`.\n- `AvroOrderChecker`: Check if the input schemas are sorted according to a fixed order \n(see `avro_sorter.py`). Fails if they are not.\n- `MetadataAdder`: Adds the `Metadata` `type` (specified as argument on the command line) as first\nfield of every domain schema. Use the `--metadata-exclude` option to exclude a comma-separated list\nof namespaces.\n- `SchemaDependenciesChecker`: Calculates all resources dependencies and assert no cycles are present.\n- `NullableOptionalExpander`: Allows for a compact definition of `nullable_optionals`\nfor \"partial entity updates\", see its specific section below.\n- `ReferencesExpander`: While Apache's `avro-tools` is able to deal with references to other\nresources in different files, Confluent's schema registry can only take one JSON as input, for \neach schema. Therefore, references to `type`s in a `domain_message` have to be expanded. \nBut with a caveat:\nonly the first reference (\"depth-first\", NOT \"breadth-first\"!) *must* be expanded. All subsequent\nreferences *must not* be expanded, i.e. they have to remain references. \n- `AvroSorter`: For the sake of readability and clearness, JSON fields of Avro resources are\nrearranged according to a fixed order (see `avro_sorter.py`). \n- `KeysGenerator`: Generates Avro Schemas for Kafka Keys automatically for every topic based\non the `partition-field` property of schema fields.\n- `SchemaMappingGenerator`: Outputs a JSON map `fully qualified schema -> kafka topic` to the file \n`schema-mapping.json`. It also gathers the field names having custom property\n`partition-field` and writes them in `schema-mapping.json`. This is done so that Kafka producers\nknow which set of fields to hash to decide which kafka partition to send a message to.\nThis module also checks that partition keys are consistent within a given Kafka topic.\nFurthermore, gathers the field names of `logicalType == user-id-fields` and stores them in\n`schema-mapping.json`. These are meant to be those fields related to users so that they\ncan be indexed separately (e.g. for GDPR.)\n- `JavaClassesCreator`: Creates Java classes using Apache's `avro-tools`. It is also a very \nconvenient way to check correctness of Avro resources.\n- `SchemaRegistryChecker`: Check if a schema is compatible with the latest version of the \nsame schema in the Schema registry.\n- `SchemaRegistrar`: Register an Avro resources (both `domain_message`s AND `type`s!)\nfor the appropriate\nKafka topic in the schema registry. `type`s are registered for a dummy topic so that we can\ncheck compatibility for them as well (it would not be possible otherwise).\nSee the documentation in `schema_registrar.py` for further documentation of `subject` \nnaming and topics.\nAutogenerated keys or the generic key for all schemas (`-k` option from the command line) are\nregistered as well.\n\n\n### Installation\n```bash\npip install avro-preprocessor\n```\n\n### Example Usage\n\nDownload Avro tools JAR\n```bash\nsh download_avro-tools.sh\n```\n\nFor help:\n```bash\navropreprocessor.py -h\n```\n\nIt is possible to define the `key_subject_name_strategy` with the `-ksns` switch.\nPossible values are`RecordNameStrategy` and `TopicRecordNameStrategy` (default).\nOnly relevant if the `SchemaRegistryChecker` and/or `SchemaRegistrar` modules are active as well.\n\nAll modules usage\n```bash\navropreprocessor.py -i schema/ -o extended-schema/ -v -s 'http://localhost:8081' -t com.jaumo.message_schema.type -d com.jaumo.message_schema.type.Metadata -p schema-mapping.json -ie 'exavsc' -a ./avro-tools-1.9.0.jar\n```\n\nNo java classes, no schema registry\n```bash\navropreprocessor.py -i schema/ -o build/schema/ -v -s 'http://localhost:8081' -t com.jaumo.message_schema.type -d com.jaumo.message_schema.type.Metadata -p build/schema-mapping.json -m DocumentationCondenser NamespaceChecker DocumentationChecker NamesChecker AvroOrderChecker MetadataAdder SchemaDependenciesChecker NullableOptionalExpander ReferencesExpander AvroSorter SchemaMappingGenerator SchemaRegistryChecker\n```\n\nOnly register to the schema registry\n```bash\navropreprocessor.py -i build/schema/ -o /tmp/ -v -s 'http://localhost:8081' -t com.jaumo.message_schema.type -ie 'avsc' -m SchemaRegistryChecker SchemaRegistrar\n```\n\nReorder the *input* schemas according to the order defined in `sort_avro.py`\n```bash\navropreprocessor.py -i schema/ -o schema/ -v -t com.jaumo.message_schema.type -ie 'exavsc' -oe 'exavsc' -m AvroSorter\n```\n\n## `nullable_optional`s: a convenient solution to the `Set-as-null` and `null-because-not-present` issue\n\nAs `protobuf`, `avro` does not distinguish between these two cases, \nunless some sort of wrapper is used.\nThe simple solution is to send the entire content of an event every time \n(i.e. always complete updates, never partial updates).\n\nHowever, since partial updates can still be useful, the module `NullableOptionalExpander` automatises \nthe following process. Let's consider a simple Avro schema for user updates:\n\n```json\n{\n \"namespace\": \"com.jaumo\",\n \"type\": \"record\",\n \"name\": \"UserUpdate\",\n \"doc\": \"Update user event\",\n \"fields\": [\n {\n \"name\": \"id\",\n \"doc\": \"The id\",\n \"type\": \"int\"\n },\n {\n \"name\": \"name\",\n \"doc\": \"The name of the user\",\n \"type\": \"string\"\n },\n {\n \"name\": \"age\",\n \"doc\": \"The age of the user\",\n \"type\": \"int\"\n },\n {\n \"name\": \"email\",\n \"doc\": \"The email of the user\",\n \"type\": \"string\"\n }\n ]\n}\n```\n\nThis schema does not support `null` values at all. In `avro`, they can be supported as follows:\n\n```json\n{\n \"namespace\": \"com.jaumo\",\n \"type\": \"record\",\n \"name\": \"UserUpdate\",\n \"doc\": \"Update user event\",\n \"fields\": [\n {\n \"name\": \"id\",\n \"doc\": \"The id\",\n \"type\": \"int\"\n },\n {\n \"name\": \"name\",\n \"doc\": \"The name of the user\",\n \"type\": [\"null\", \"string\"],\n \"default\": null\n },\n {\n \"name\": \"age\",\n \"doc\": \"The age of the user\",\n \"type\": [\"null\", \"int\"],\n \"default\": null\n },\n {\n \"name\": \"email\",\n \"doc\": \"The email of the user\",\n \"type\": [\"null\", \"string\"],\n \"default\": null\n }\n ]\n}\n```\n\nWith the schema above, both `set-as-null` and `null-because-not-present` are just null,\nso they are still ambiguous. To distinguish them, we can wrap around a record type \n(which in Java will be a specific class). Showing the `email` property only, this would be\n\n```json\n{\n \"name\": \"email\",\n \"doc\": \"The email of the user\",\n \"default\": null,\n \"type\": [\n \"null\",\n {\n \"name\": \"OptionalString\",\n \"type\": \"record\",\n \"fields\": [\n {\n \"name\": \"value\",\n \"default\": null,\n \"type\": [\n \"null\",\n \"string\"\n ]\n }\n ]\n }\n ]\n}\n```\n\nNote how the name of the wrapper record (`\"OptionalString\"`, above)\ncomes from the prefix `Optional` and the capitalised version of the Avro type field (`string`).\nThe name of the inner property is always `\"value\"` (this is done automatically, see below).\n\nNow we have three cases\n- `email` set to null means `null-because-not-present`\n- `email.value` set to null means `set-as-null`\n- `email.value` set to string\n\nSince there's a lot of boilerplate and thus this is error-prone, the `nullable_optional` \nis simple extension to the Avro syntax that adds the property `\"nullable_optional\": true`. \nIf a field has this property set to \n`true`, the field is expanded with its wrapper. The schema above then becomes:\n\n```json\n{\n \"name\": \"email\",\n \"doc\": \"The email of the user\",\n \"nullable_optional\": true,\n \"type\": \"string\"\n}\n``` \n\nand it is saved to a `.exavsc` file.\n\nNote how this step is completely **language independent**: its output is a \ncompletely standard Avro schema that can be used by any library or framework. \n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://gitlab.com/Jaumo/avro-preprocessor", "keywords": "avro,preprocessor,schema,schemas,schemata", "license": "Apache2", "maintainer": "", "maintainer_email": "", "name": "avro-preprocessor", "package_url": "https://pypi.org/project/avro-preprocessor/", "platform": "", "project_url": "https://pypi.org/project/avro-preprocessor/", "project_urls": { "Homepage": "https://gitlab.com/Jaumo/avro-preprocessor" }, "release_url": "https://pypi.org/project/avro-preprocessor/0.0.55/", "requires_dist": [ "networkx (==2.2)", "pygments (==2.2.0)", "requests (==2.20.0)" ], "requires_python": "", "summary": "A preprocessor for Avro Schemata", "version": "0.0.55" }, "last_serial": 5286003, "releases": { "0.0.38": [ { "comment_text": "", "digests": { "md5": "da907cf5789f14f46d060e8304bee694", "sha256": "ea19e50b0a2e3284dc8fa32ba81aecaad550ff1ca196444409d56138c253cf68" }, "downloads": -1, "filename": "avro_preprocessor-0.0.38-py3-none-any.whl", "has_sig": false, "md5_digest": "da907cf5789f14f46d060e8304bee694", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 36618, "upload_time": "2018-12-18T00:01:36", "url": "https://files.pythonhosted.org/packages/b3/94/20a2a86b015ab7c143ad3351c193f36879bce084c9683617b1fe60a45bf1/avro_preprocessor-0.0.38-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4b31eefa0c8aa66b4e7ec4496cebf0c9", "sha256": "ebe7f2e8914b6c2784cc2eb6ea66ca6d31d9cfcb6dc2f4e5afc9f408b7a34eae" }, "downloads": -1, "filename": "avro-preprocessor-0.0.38.tar.gz", "has_sig": false, "md5_digest": "4b31eefa0c8aa66b4e7ec4496cebf0c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25755, "upload_time": "2018-12-18T00:01:37", "url": "https://files.pythonhosted.org/packages/4c/d8/dc4608240acd8b26f28240b09d3c8095d87530631c6d9247741f55e878e0/avro-preprocessor-0.0.38.tar.gz" } ], "0.0.40": [ { "comment_text": "", "digests": { "md5": "d69ac9584a857317e42eff091f1ab9fa", "sha256": "5f55bdbc7a07e562817e5cf1e8aa725f46fde131dd48fcc259c08deebe7847fb" }, "downloads": -1, "filename": "avro_preprocessor-0.0.40-py3-none-any.whl", "has_sig": false, "md5_digest": "d69ac9584a857317e42eff091f1ab9fa", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 37304, "upload_time": "2018-12-18T03:24:02", "url": "https://files.pythonhosted.org/packages/d8/24/71369512f93cae99763a02cccde288767527919e441bf4e4e815f1dff6fb/avro_preprocessor-0.0.40-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6d74eb82e65ab01d1f390df038986b19", "sha256": "d62e04c54dee17dd4c9821d0a170295f75ae43f8ec7d36760468ebe9ee014ddd" }, "downloads": -1, "filename": "avro-preprocessor-0.0.40.tar.gz", "has_sig": false, "md5_digest": "6d74eb82e65ab01d1f390df038986b19", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26386, "upload_time": "2018-12-18T03:24:03", "url": "https://files.pythonhosted.org/packages/6b/e9/fe92d7cbb29478336baa113e057f4414da74f59834480cc55e1c2ef14060/avro-preprocessor-0.0.40.tar.gz" } ], "0.0.41": [ { "comment_text": "", "digests": { "md5": "35f5848df0bb247ffa485d3e8b99f4af", "sha256": "1f20ffff5d1dd5ad26ccbb4168dc05065d78faa7a551311b268baad9e6768e46" }, "downloads": -1, "filename": "avro_preprocessor-0.0.41-py3-none-any.whl", "has_sig": false, "md5_digest": "35f5848df0bb247ffa485d3e8b99f4af", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 37249, "upload_time": "2018-12-20T01:53:47", "url": "https://files.pythonhosted.org/packages/5b/ff/58873c2c656bcc0a19c6f82ba756eba43e29cd8a2ef1087856d31d21a658/avro_preprocessor-0.0.41-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "35185a809831b76c7df62f9ad6c5f0f9", "sha256": "75ba39d1d3bbfc36e4f82aedef20e3759392540e6b06494de11946f7c6aa16f8" }, "downloads": -1, "filename": "avro-preprocessor-0.0.41.tar.gz", "has_sig": false, "md5_digest": "35185a809831b76c7df62f9ad6c5f0f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26282, "upload_time": "2018-12-20T01:53:48", "url": "https://files.pythonhosted.org/packages/4a/d5/51478ec8c02d986813c7f5387e5457d5c0ad238c3df043cad97806dcee2d/avro-preprocessor-0.0.41.tar.gz" } ], "0.0.42": [ { "comment_text": "", "digests": { "md5": "e7b90401e918ba75705fb1be5b19ee90", "sha256": "850b590d1916e15bf4f4d8c291163fa7e1c412f980ec3f7db68e37c1b07355bf" }, "downloads": -1, "filename": "avro_preprocessor-0.0.42-py3-none-any.whl", "has_sig": false, "md5_digest": "e7b90401e918ba75705fb1be5b19ee90", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 37250, "upload_time": "2018-12-20T02:00:56", "url": "https://files.pythonhosted.org/packages/cd/6d/6f77c7097fb113679157c892c4da90b9a2fe02273a443fa4b6a7e5afbdc9/avro_preprocessor-0.0.42-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1cb9dca36ddb1525c61142bc9ee17f90", "sha256": "4495ac2eba383f3eab6b0f67f48ddbbabab3cc68efbea3e883bf0937c6b0ee85" }, "downloads": -1, "filename": "avro-preprocessor-0.0.42.tar.gz", "has_sig": false, "md5_digest": "1cb9dca36ddb1525c61142bc9ee17f90", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26290, "upload_time": "2018-12-20T02:00:57", "url": "https://files.pythonhosted.org/packages/a6/a9/40fec09493a3fed9bddfd0fc629a1f2eddb36b52e21feae4309490a2ca70/avro-preprocessor-0.0.42.tar.gz" } ], "0.0.43": [ { "comment_text": "", "digests": { "md5": "4fc9e1970143bc307fbea768c9f48985", "sha256": "b7337b1b91c3cbad5f18901f0f70bed4c5564eb46ddedf37c3fba6114bf11659" }, "downloads": -1, "filename": "avro_preprocessor-0.0.43-py3-none-any.whl", "has_sig": false, "md5_digest": "4fc9e1970143bc307fbea768c9f48985", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 37779, "upload_time": "2019-01-24T16:42:17", "url": "https://files.pythonhosted.org/packages/73/97/d2fc7be5e271cfb9420647f85bbb465e22023773dd251ac416932f20cb35/avro_preprocessor-0.0.43-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "93bd4e61fa0b1fa6c75f1636fbc672ea", "sha256": "a93efbbee1aaeb709dc05a8f85ea6c828e3a3375933dead79b0ceb29324dcb84" }, "downloads": -1, "filename": "avro-preprocessor-0.0.43.tar.gz", "has_sig": false, "md5_digest": "93bd4e61fa0b1fa6c75f1636fbc672ea", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26751, "upload_time": "2019-01-24T16:42:19", "url": "https://files.pythonhosted.org/packages/b1/0f/ca9ee44986ccbbfdd749c0b18e4bbe26bc81fc9298304c59ceedeb4a4d23/avro-preprocessor-0.0.43.tar.gz" } ], "0.0.44": [ { "comment_text": "", "digests": { "md5": "0d344cf6566dba5089c40e441dc64a57", "sha256": "2f1a23c4d7f1a16679b372fa06ca3e52ced51f22cd91ab9c2d606a3342deb3c8" }, "downloads": -1, "filename": "avro_preprocessor-0.0.44-py3-none-any.whl", "has_sig": false, "md5_digest": "0d344cf6566dba5089c40e441dc64a57", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38086, "upload_time": "2019-01-29T14:28:00", "url": "https://files.pythonhosted.org/packages/53/d4/ed6b10d65f0d0a5f28616132af92ba811e3859a000c73264e93216d9b2e4/avro_preprocessor-0.0.44-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8cb94926c74899e9137d099b86ca2aae", "sha256": "8da919034586f009ba258a6b1cd8627a7c47e3d952ccc10b0a5a68514e0633b5" }, "downloads": -1, "filename": "avro-preprocessor-0.0.44.tar.gz", "has_sig": false, "md5_digest": "8cb94926c74899e9137d099b86ca2aae", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27228, "upload_time": "2019-01-29T14:28:02", "url": "https://files.pythonhosted.org/packages/a1/1c/69716f0a077fe45570cd20a0180e511dd43727e522972810f8ec722bbcd8/avro-preprocessor-0.0.44.tar.gz" } ], "0.0.45": [ { "comment_text": "", "digests": { "md5": "b6f33663245d215137a30a82f4a6f297", "sha256": "dfa9dc361b29afcea2db92045b794a8fe6cf0b320d24bc42589562044263034b" }, "downloads": -1, "filename": "avro_preprocessor-0.0.45-py3-none-any.whl", "has_sig": false, "md5_digest": "b6f33663245d215137a30a82f4a6f297", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38095, "upload_time": "2019-02-04T09:57:39", "url": "https://files.pythonhosted.org/packages/6c/bc/fba67dae6556321f42ae03a0b9c593b35a336c3c6c553fa4867f63a5496f/avro_preprocessor-0.0.45-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b360e24803abca66d03839f31c55f64e", "sha256": "a0eb8a128ff5b3f0a48bfc8894f83550aee708e76cc78a6d5c6d2c23aba44edf" }, "downloads": -1, "filename": "avro-preprocessor-0.0.45.tar.gz", "has_sig": false, "md5_digest": "b360e24803abca66d03839f31c55f64e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27234, "upload_time": "2019-02-04T09:57:41", "url": "https://files.pythonhosted.org/packages/9f/50/fca6fd2e488ef21ea408fc69456b71c1455ccbd6429ddbf7b3395227534e/avro-preprocessor-0.0.45.tar.gz" } ], "0.0.47": [ { "comment_text": "", "digests": { "md5": "31f979b26f6f2d676315c797cca9a3b6", "sha256": "37fb5aeabae930bc9f6f806f97e23785cfb208c66127da33db8f28daed2b4812" }, "downloads": -1, "filename": "avro_preprocessor-0.0.47-py3-none-any.whl", "has_sig": false, "md5_digest": "31f979b26f6f2d676315c797cca9a3b6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38537, "upload_time": "2019-02-07T12:07:47", "url": "https://files.pythonhosted.org/packages/a0/4e/7bc1ff853a7d13c248569ba9428a6b1a17c36b6671a9be1ff73897229902/avro_preprocessor-0.0.47-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eab1bfdb24644c95d12cd8eba809ce35", "sha256": "43282d8e72740b76fddf6e36c7d38edafce47c9426c85a6097f5e1bae39413d6" }, "downloads": -1, "filename": "avro-preprocessor-0.0.47.tar.gz", "has_sig": false, "md5_digest": "eab1bfdb24644c95d12cd8eba809ce35", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27623, "upload_time": "2019-02-07T12:07:48", "url": "https://files.pythonhosted.org/packages/c8/09/52540b3a4f61f98d0739624840aa81614555126a99d16ea710a6491f6603/avro-preprocessor-0.0.47.tar.gz" } ], "0.0.48": [ { "comment_text": "", "digests": { "md5": "4e59b2b5ef30175103407ef8b4d4bb9e", "sha256": "1f00efb7590c149264e296d525685db8904203a0bc2ce1c0f05094b01598d03b" }, "downloads": -1, "filename": "avro_preprocessor-0.0.48-py3-none-any.whl", "has_sig": false, "md5_digest": "4e59b2b5ef30175103407ef8b4d4bb9e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38538, "upload_time": "2019-02-07T12:37:22", "url": "https://files.pythonhosted.org/packages/cc/ab/7c166c895079eda50e46311f9a82e45822fe46f67bd4c82539788e2c23be/avro_preprocessor-0.0.48-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9f2110e1dcf51a598e10adf9afa583e8", "sha256": "21be975d54140dbf38a7ff9cfe943b85edf1291e25a8184dd912e9fc457e9985" }, "downloads": -1, "filename": "avro-preprocessor-0.0.48.tar.gz", "has_sig": false, "md5_digest": "9f2110e1dcf51a598e10adf9afa583e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27619, "upload_time": "2019-02-07T12:37:23", "url": "https://files.pythonhosted.org/packages/91/5d/eac7dfa76420c9f44557deeaa895df798691f809e97d0e81da968769295a/avro-preprocessor-0.0.48.tar.gz" } ], "0.0.49": [ { "comment_text": "", "digests": { "md5": "bdb3a7cb459b4f0353a577b8216312c1", "sha256": "960aa82afe5f8e8422b59b1a22398ebf65997c242bde5bd7cadab816dd1c0fe6" }, "downloads": -1, "filename": "avro_preprocessor-0.0.49-py3-none-any.whl", "has_sig": false, "md5_digest": "bdb3a7cb459b4f0353a577b8216312c1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38546, "upload_time": "2019-02-12T15:18:07", "url": "https://files.pythonhosted.org/packages/9a/4b/06245b6620dc1c1aabf38c3b877ad3ea67d5ace1e3f91da05d8609857e08/avro_preprocessor-0.0.49-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "640605e3eac71585afe8f85db0a03028", "sha256": "ba4866d50b05dc3c9fa6ce5d987c4f4cac2a6f305922978aeb7ea5e1eda650dc" }, "downloads": -1, "filename": "avro-preprocessor-0.0.49.tar.gz", "has_sig": false, "md5_digest": "640605e3eac71585afe8f85db0a03028", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27629, "upload_time": "2019-02-12T15:18:09", "url": "https://files.pythonhosted.org/packages/5c/c7/e5023035e289a5c667adfbd3e7ee7d8029d6e23402dae4fa657e5ff2cdb8/avro-preprocessor-0.0.49.tar.gz" } ], "0.0.50": [ { "comment_text": "", "digests": { "md5": "d318f1cfaa8e4be814fc41539f8e6bbf", "sha256": "fc43fac291354c0d860bb61a31bd9f4f56a6884148f4c990705e51940df90d2a" }, "downloads": -1, "filename": "avro_preprocessor-0.0.50-py3-none-any.whl", "has_sig": false, "md5_digest": "d318f1cfaa8e4be814fc41539f8e6bbf", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38555, "upload_time": "2019-02-12T17:51:23", "url": "https://files.pythonhosted.org/packages/ba/80/304d5c9f21b8d753ef1c8628354a57896d143688acccd6f47d616ad5baa0/avro_preprocessor-0.0.50-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8c8a2cccdd53a97fabe45496d35b947b", "sha256": "97c6008f3c9bb9230108d4ae4662a5e1b5a04867357fcbaabbf416380cb36666" }, "downloads": -1, "filename": "avro-preprocessor-0.0.50.tar.gz", "has_sig": false, "md5_digest": "8c8a2cccdd53a97fabe45496d35b947b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27630, "upload_time": "2019-02-12T17:51:24", "url": "https://files.pythonhosted.org/packages/97/16/18f75e4d87121d1b431e6b8b560ec4e7e65c79a1fc20832e63335f4e22e0/avro-preprocessor-0.0.50.tar.gz" } ], "0.0.51": [ { "comment_text": "", "digests": { "md5": "e3d1a1018dc232b085242a89cd33d940", "sha256": "af8a8d7882ca76d168d8e6cf1f698249baec2f3d79f34cdeaf6088ff39b12aac" }, "downloads": -1, "filename": "avro_preprocessor-0.0.51-py3-none-any.whl", "has_sig": false, "md5_digest": "e3d1a1018dc232b085242a89cd33d940", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38799, "upload_time": "2019-03-21T11:27:14", "url": "https://files.pythonhosted.org/packages/65/a8/aad8ccb1147d960de9ce3d63e5dad2d796073caef7e0edee17ee97d66e9f/avro_preprocessor-0.0.51-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "725e63eed44e31998544bfb15c51bcbf", "sha256": "0d0ca0297c074dc6eda8fdea9df710d48ce661c9c9da366ef6d11278d9de5d8b" }, "downloads": -1, "filename": "avro-preprocessor-0.0.51.tar.gz", "has_sig": false, "md5_digest": "725e63eed44e31998544bfb15c51bcbf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27938, "upload_time": "2019-03-21T11:27:16", "url": "https://files.pythonhosted.org/packages/1c/db/b6aa9ceea204a10883073184533f4921252159951b29fb8df6031919e96e/avro-preprocessor-0.0.51.tar.gz" } ], "0.0.52": [ { "comment_text": "", "digests": { "md5": "fb32c21e2c8eddcce802db2210ee1c60", "sha256": "67a9d7238c452de0093868720186f94094f523f79d4fb6d2b01e4bbb3b277a11" }, "downloads": -1, "filename": "avro_preprocessor-0.0.52-py3-none-any.whl", "has_sig": false, "md5_digest": "fb32c21e2c8eddcce802db2210ee1c60", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38939, "upload_time": "2019-03-21T12:50:30", "url": "https://files.pythonhosted.org/packages/57/37/76b53c77a052a40f08c174523c67277279a97045b360f4b5d6a0ed8f0277/avro_preprocessor-0.0.52-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0691843dbcd941b6598714234dd9ca6b", "sha256": "63dd10b137dac5cc3ef27bf6fada257b986738a07086e5aeed46cdeb300cc661" }, "downloads": -1, "filename": "avro-preprocessor-0.0.52.tar.gz", "has_sig": false, "md5_digest": "0691843dbcd941b6598714234dd9ca6b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28008, "upload_time": "2019-03-21T12:50:31", "url": "https://files.pythonhosted.org/packages/4f/52/54ba0493165cc151962d0eda9c22bb21503b5798b5d140c3069986c088bc/avro-preprocessor-0.0.52.tar.gz" } ], "0.0.53": [ { "comment_text": "", "digests": { "md5": "e0ce1f5883578e1319ebe649ccc3d956", "sha256": "6cbc669d5fffbc6956d941d7775511f15f5957832d67cd52eca967136a3103ca" }, "downloads": -1, "filename": "avro_preprocessor-0.0.53-py3-none-any.whl", "has_sig": false, "md5_digest": "e0ce1f5883578e1319ebe649ccc3d956", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 39031, "upload_time": "2019-03-25T10:25:41", "url": "https://files.pythonhosted.org/packages/5d/22/476dea1e12e692f80e751421736f247f374c065920a4fa912e6a375ce34b/avro_preprocessor-0.0.53-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a54f829f13c9c6e552dfb496f74a22f9", "sha256": "eef64f19b328c0e08b2b124b24e1271f19c0ea8705bbc768e9a5d2cdae259a6c" }, "downloads": -1, "filename": "avro-preprocessor-0.0.53.tar.gz", "has_sig": false, "md5_digest": "a54f829f13c9c6e552dfb496f74a22f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28057, "upload_time": "2019-03-25T10:25:42", "url": "https://files.pythonhosted.org/packages/2e/9f/3868d82a3dda5ce617aaf6d288cdb1b404b02bad96935bf5a0c61c93caab/avro-preprocessor-0.0.53.tar.gz" } ], "0.0.54": [ { "comment_text": "", "digests": { "md5": "dfeb13a6b07cb4770547cbf7c01112d1", "sha256": "d5da6bf05258d23f3427e803621bf27f4dd15b09f52733c257c8055d52ce702d" }, "downloads": -1, "filename": "avro_preprocessor-0.0.54-py3-none-any.whl", "has_sig": false, "md5_digest": "dfeb13a6b07cb4770547cbf7c01112d1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 39081, "upload_time": "2019-04-17T14:02:00", "url": "https://files.pythonhosted.org/packages/51/71/d9660fdbfc12b029aa87338971d0068c7b8bf615fed88694c21eaebb8cb3/avro_preprocessor-0.0.54-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9b71b7466b25cf62963b71571083127f", "sha256": "74ff5a99ce5c96e7ca7aeb8ef07174ffb237b8349c11dc6f82995cd308531a31" }, "downloads": -1, "filename": "avro-preprocessor-0.0.54.tar.gz", "has_sig": false, "md5_digest": "9b71b7466b25cf62963b71571083127f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28097, "upload_time": "2019-04-17T14:02:01", "url": "https://files.pythonhosted.org/packages/04/39/665131a10ea9b8f1c264e006d83c7fbe270e631192134990e269b8ace0a5/avro-preprocessor-0.0.54.tar.gz" } ], "0.0.55": [ { "comment_text": "", "digests": { "md5": "766b4dc5bdab1815314d6e73dff38cb9", "sha256": "1e0c3242eb123d2f6a1c7dc126768b2a302381d90ec75ef8a9e509562e833be9" }, "downloads": -1, "filename": "avro_preprocessor-0.0.55-py3-none-any.whl", "has_sig": false, "md5_digest": "766b4dc5bdab1815314d6e73dff38cb9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 39761, "upload_time": "2019-05-18T15:42:37", "url": "https://files.pythonhosted.org/packages/cc/39/392fc3438203f685397d667aa609bc58713e19dd9a19a802c2d4b9c99173/avro_preprocessor-0.0.55-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "28ab84ca9bb6c9572416c6872f11fa42", "sha256": "40057ae9c7e0d2f7c26769a2506224b5d086846dac26e2639194c58b20a6405f" }, "downloads": -1, "filename": "avro-preprocessor-0.0.55.tar.gz", "has_sig": false, "md5_digest": "28ab84ca9bb6c9572416c6872f11fa42", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28096, "upload_time": "2019-05-18T15:42:38", "url": "https://files.pythonhosted.org/packages/6d/c7/d7750beeaab4869da547f2cea97b0369a9456ac402af24930a3e46005edf/avro-preprocessor-0.0.55.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "766b4dc5bdab1815314d6e73dff38cb9", "sha256": "1e0c3242eb123d2f6a1c7dc126768b2a302381d90ec75ef8a9e509562e833be9" }, "downloads": -1, "filename": "avro_preprocessor-0.0.55-py3-none-any.whl", "has_sig": false, "md5_digest": "766b4dc5bdab1815314d6e73dff38cb9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 39761, "upload_time": "2019-05-18T15:42:37", "url": "https://files.pythonhosted.org/packages/cc/39/392fc3438203f685397d667aa609bc58713e19dd9a19a802c2d4b9c99173/avro_preprocessor-0.0.55-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "28ab84ca9bb6c9572416c6872f11fa42", "sha256": "40057ae9c7e0d2f7c26769a2506224b5d086846dac26e2639194c58b20a6405f" }, "downloads": -1, "filename": "avro-preprocessor-0.0.55.tar.gz", "has_sig": false, "md5_digest": "28ab84ca9bb6c9572416c6872f11fa42", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28096, "upload_time": "2019-05-18T15:42:38", "url": "https://files.pythonhosted.org/packages/6d/c7/d7750beeaab4869da547f2cea97b0369a9456ac402af24930a3e46005edf/avro-preprocessor-0.0.55.tar.gz" } ] }