├── .github ├── ISSUE_TEMPLATE │ ├── 01_question.md │ ├── 02_bug.md │ ├── 03_feature.md │ └── config.yml └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .gitpod.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README-gitpod.md ├── README.md ├── data_rolling.json ├── main.py ├── metricadvancedproducer.py ├── metricproducer.py ├── pizzaproducer.py ├── realstockproducer.py ├── requirements.txt ├── rolling.py ├── stockproducer.py ├── userbehaviorproducer.py └── userbets.py /.github/ISSUE_TEMPLATE/01_question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ❓ Ask a question 3 | about: Got stuck or missing something from the docs? Ask away! 4 | --- 5 | 6 | # What can we help you with? 7 | 8 | 9 | 10 | # Where would you expect to find this information? 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/02_bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐜 Report a bug 3 | about: Spotted a problem? Let us know 4 | --- 5 | 6 | # What happened? 7 | 8 | 9 | 10 | # What did you expect to happen? 11 | 12 | 13 | 14 | # What else do we need to know? 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/03_feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💡 Feature suggestion 3 | about: What would make this even better? 4 | --- 5 | 6 | # What is currently missing? 7 | 8 | 9 | 10 | # How could this be improved? 11 | 12 | 13 | 14 | # Is this a feature you would work on yourself? 15 | 16 | * [ ] I plan to open a pull request for this feature 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Aiven Security Bug Bounty 4 | url: https://hackerone.com/aiven_ltd 5 | about: Our bug bounty program. 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | # About this change - What it does 3 | 4 | 5 | 6 | 7 | Resolves: #xxxxx 8 | 9 | # Why this way 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/certs 2 | .vscode 3 | *.pyc 4 | venv -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: pip install -r requirements.txt 3 | name: install requierements 4 | - name: Install avn CLI 5 | init: pip install aiven-client 6 | - name: Open Readme 7 | command: gp preview https://aiven.io/developer/create-your-own-data-stream-for-kafka-with-python-and-faker -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | opensource@aiven.io. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Welcome! 2 | 3 | Contributions are very welcome on Python Fake Data Producer For Aiven for Apache Kafka. When contributing please keep this in mind: 4 | 5 | - Open an issue to discuss new bigger features. 6 | - Write code consistent with the project style and make sure the tests are passing. 7 | - Stay in touch with us if we have follow up questions or requests for further changes. 8 | 9 | # Opening a PR 10 | 11 | - Commit messages should describe the changes, not the filenames. Win our admiration by following 12 | the [excellent advice from Chris Beams](https://chris.beams.io/posts/git-commit/) when composing 13 | commit messages. 14 | - Choose a meaningful title for your pull request. 15 | - The pull request description should focus on what changed and why. 16 | - Check that the tests pass (and add test coverage for your changes if appropriate). 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README-gitpod.md: -------------------------------------------------------------------------------- 1 | # Quickstart with Gitpod 2 | 3 | This workspace comes with some pre-installed stuff for you : 4 | 5 | * Python requirements have already been installed 6 | * avn CLI has already been installed 7 | * jq has benn installed 8 | 9 | First make sure to have an Aiven account, otherwise you are just a few clicks away of creating one [here](https://console.aiven.io/signup?utm_source=github&utm_medium=organic&utm_campaign=blog_art&utm_content=post) 10 | 11 | Then make sure to get an personal access token, check this [video](https://www.youtube.com/watch?v=64G2QIMYOL4) to learn how to get one. 12 | 13 | Open a terminal, you'll need to copy-paste or re-type all the bash commands below. 14 | 15 | Now you can login : 16 | 17 | ```bash 18 | avn user login --token 19 | 20 | ``` 21 | 22 | Create a `certs` folder : 23 | 24 | ```bash 25 | mkdir certs 26 | ``` 27 | 28 | Set your variables : 29 | ```bash 30 | KAFKA_INSTANCE_NAME=my-kafka-demo 31 | CLOUD_REGION=aws-eu-south-1 32 | AIVEN_PLAN_NAME=startup-2 33 | DESTINATION_FOLDER_NAME=certs 34 | ``` 35 | 36 | If you haven't yet, create a Aiven for Apache Kafka service : 37 | 38 | ```bash 39 | avn service create $KAFKA_INSTANCE_NAME \ 40 | -t kafka \ 41 | --cloud $CLOUD_REGION \ 42 | -p $AIVEN_PLAN_NAME \ 43 | -c kafka.auto_create_topics_enable=true \ 44 | -c kafka_rest=true 45 | 46 | ``` 47 | 48 | Retrieve your host and port from the console and set them : 49 | And retrieve the Apache Kafka Service URI with 50 | 51 | ```bash 52 | 53 | KAFKA_HOST=$(avn service get $KAFKA_INSTANCE_NAME --json | jq -r '.service_uri_params.host') 54 | KAFKA_PORT=$(avn service get $KAFKA_INSTANCE_NAME --json | jq -r '.service_uri_params.port') 55 | 56 | ``` 57 | 58 | You can wait for the newly created Apache Kafka instance to be ready with : 59 | 60 | ```bash 61 | avn service wait $KAFKA_INSTANCE_NAME 62 | ``` 63 | 64 | Now get your certificates : 65 | 66 | ```bash 67 | avn service user-creds-download $KAFKA_INSTANCE_NAME \ 68 | -d $DESTINATION_FOLDER_NAME \ 69 | --username avnadmin 70 | ``` 71 | 72 | And finally run the demo : 73 | 74 | ```bash 75 | 76 | python main.py \ 77 | --security-protocol ssl \ 78 | --cert-folder $DESTINATION_FOLDER_NAME\ 79 | --host $KAFKA_HOST \ 80 | --port $KAFKA_PORT \ 81 | --topic-name pizza-orders \ 82 | --nr-messages 0 \ 83 | --max-waiting-time 2 \ 84 | --subject pizza 85 | 86 | ``` 87 | 88 | You should see a continuous flow of data being pushed to Apache Kafka, to the topic defined by the `--topic-name` parameter. You can either use the Aiven console, or tools like [kcat](https://docs.aiven.io/docs/products/kafka/howto/kcat) to browse the data. 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Fake Data Producer for Apache Kafka® 2 | 3 | ## Description 4 | 5 | **Python Fake Data Producer for Apache Kafka®** is a complete demo app allowing you to quickly produce a Python fake Pizza-based streaming dataset and push it to an Apache Kafka® topic. It gives an example on how easy is to create great fake streaming data to feed Apache Kafka. 6 | 7 | * **Apache Kafka**: a [distributed streaming platform](https://kafka.apache.org/) 8 | * **Topic**: all Apache Kafka records are organised into topics, you can think of a topic like an event log or a table if you're familiar with databases. 9 | * **Apache Kafka Producer**: an entity/application that publishes data to Apache Kafka 10 | 11 | An Apache Apache Kafka cluster can be created in minutes in any cloud of your choice using [Aiven.io console](https://console.aiven.io/signup?utm_source=github&utm_medium=organic&utm_campaign=blog_art&utm_content=post). 12 | 13 | For more informations about the code building blogs check the [blog post](https://aiven.io/blog/create-your-own-data-stream-for-kafka-with-python-and-faker?utm_source=github&utm_medium=organic&utm_campaign=blog_art&utm_content=post) 14 | 15 | 16 | ## Installation 17 | This demo app is relying on [Faker](https://faker.readthedocs.io/en/master/) and [kafka-python](https://kafka-python.readthedocs.io/en/master/usage.html) which the former requiring Python 3.5 and above. 18 | The installation can be done via 19 | 20 | ```bash 21 | pip install -r requirements.txt 22 | ``` 23 | 24 | ## Usage 25 | 26 | The Python code can be run in bash with the following, 27 | in ``SSL`` security protocol: 28 | ```bash 29 | python main.py \ 30 | --security-protocol ssl \ 31 | --cert-folder ~/kafkaCerts/ \ 32 | --host kafka-.aivencloud.com \ 33 | --port 13041 \ 34 | --topic-name pizza-orders \ 35 | --nr-messages 0 \ 36 | --max-waiting-time 0 \ 37 | --subject pizza 38 | ``` 39 | in ``SASL_SSL`` security protocol: 40 | ```bash 41 | python main.py \ 42 | --security-protocol SASL_SSL \ 43 | --sasl-mechanism SCRAM-SHA-256 \ 44 | --username \ 45 | --password \ 46 | --cert-folder ~/kafkaCerts/ \ 47 | --host kafka-.aivencloud.com \ 48 | --port 13041 \ 49 | --topic-name pizza-orders \ 50 | --nr-messages 0 \ 51 | --max-waiting-time 0 \ 52 | --subject pizza 53 | ``` 54 | in ``PLAINTEXT`` security protocol: 55 | ```bash 56 | python main.py \ 57 | --security-protocol plaintext \ 58 | --host your-kafka-broker-host \ 59 | --port 9092 \ 60 | --topic-name pizza-orders \ 61 | --nr-messages 0 \ 62 | --max-waiting-time 0 \ 63 | --subject pizza 64 | ``` 65 | Where 66 | * `security-protocol`: Security protocol for Kafka. ``PLAINTEXT``, ``SSL`` or ``SASL_SSL`` are supported. 67 | * `cert-folder`: points to the folder containing the Apache Kafka CA certificate, Access certificate and Access key (see [blog post](https://aiven.io/blog/create-your-own-data-stream-for-kafka-with-python-and-faker?utm_source=github&utm_medium=organic&utm_campaign=blog_art&utm_content=post) for more) 68 | * `host`: the Apache Kafka host 69 | * `port`: the Apache Kafka port 70 | * `topic-name`: the Apache Kafka topic name to write to (the topic needs to be pre-created or `kafka.auto_create_topics_enable` parameter enabled) 71 | * `nr-messages`: the number of messages to send 72 | * `max-waiting-time`: the maximum waiting time in seconds between messages 73 | * `subject`: select amongst various subjects: `pizza` is the default one, but you can generate also `userbehaviour`, `bet`, `stock`, `realstock` (using the yahoo finance apis), `metric`, `advancedmetric`, and `rolling`. 74 | 75 | If successfully connected to a Apache Kafka cluster, the command will output a number of messages (`nr-messages` parameter) that are been sent to Apache Kafka in the form 76 | 77 | ```json 78 | { 79 | "id": 0, 80 | "shop": "Circular Pi Pizzeria", 81 | "name": "Jason Brown", 82 | "phoneNumber": "(510)290-7469", 83 | "address": "2701 Samuel Summit Suite 938\nRyanbury, PA 62847", 84 | "pizzas": [{ 85 | "pizzaName": "Diavola", 86 | "additionalToppings": [] 87 | }, { 88 | "pizzaName": "Mari & Monti", 89 | "additionalToppings": ["olives", "garlic", "anchovies"] 90 | }, { 91 | "pizzaName": "Diavola", 92 | "additionalToppings": ["onion", "anchovies", "mozzarella", "olives"] 93 | }] 94 | } 95 | ``` 96 | 97 | With 98 | * `id`: being the order number, starting from `0` until `nr-messages -1` 99 | * `shop`: is the pizza shop name receiving the order, you can check and change the full list of shops in the `pizza_shop` function within [pizzaproducer.py](pizzaproducer.py) 100 | * `name`: the caller name 101 | * `phoneNumber`: the caller phone number 102 | * `address`: the caller address 103 | * `pizzas`: an array or pizza orders made by 104 | * `pizzaName`: the name of the basic pizza in the range from 1 to `MAX_NUMBER_PIZZAS_IN_ORDER` defined in [main.py](main.py), the list of available pizzas can be found in the `pizza_name` function within [pizzaproducer.py](pizzaproducer.py) 105 | * `additionalToppings`: an optional number of additional toppings added to the pizza in the range from 0 to `MAX_ADDITIONAL_TOPPINGS_IN_PIZZA` , the list of available toppings can be found in the `pizza_topping` function within [pizzaproducer.py](pizzaproducer.py) 106 | 107 | # Starting your Apache Kafka Service with Aiven.io 108 | 109 | If you don't have a Apache Kafka Cluster available, you can easily start one in [Aiven.io console](https://console.aiven.io/signup?utm_source=github&utm_medium=organic&utm_campaign=blog_art&utm_content=post). 110 | 111 | Once created your account you can start your Apache Kafka service with [Aiven.io's cli](https://github.com/aiven/aiven-client) 112 | 113 | Set your variables first: 114 | ```bash 115 | KAFKA_INSTANCE_NAME=fafka-my 116 | PROJECT_NAME=my-project 117 | CLOUD_REGION=aws-eu-south-1 118 | AIVEN_PLAN_NAME=business-4 119 | DESTINATION_FOLDER_NAME=~/kafkacerts 120 | ``` 121 | Parameters: 122 | * `KAFKA_INSTANCE_NAME`: the name you want to give to the Apache Kafka instance 123 | * `PROJECT_NAME`: the name of the project created during sing-up 124 | * `CLOUD_REGION`: the name of the Cloud region where the instance will be created. The list of cloud regions can be found 125 | with 126 | ```bash 127 | avn cloud list 128 | ``` 129 | * `AIVEN_PLAN_NAME`: name of Aiven's plan to use, which will drive the resources available, the list of plans can be found with 130 | ```bash 131 | avn service plans --project -t kafka --cloud 132 | ``` 133 | * `DESTINATION_FOLDER_NAME`: local folder where Apache Kafka certificates will be stored (used to login) 134 | 135 | You can create the Apache Kafka service with 136 | 137 | ```bash 138 | avn service create \ 139 | -t kafka $KAFKA_INSTANCE_NAME \ 140 | --project $PROJECT_NAME \ 141 | --cloud $CLOUD_PROVIDER \ 142 | -p $AIVEN_PLAN_NAME \ 143 | -c kafka_rest=true \ 144 | -c kafka.auto_create_topics_enable=true \ 145 | -c schema_registry=true 146 | ``` 147 | 148 | --- 149 | 150 | You can download the required SSL certificates in the `` with 151 | 152 | ```bash 153 | avn service user-creds-download $KAFKA_SERVICE_NAME \ 154 | --project $PROJECT_NAME \ 155 | -d $DESTINATION_FOLDER_NAME \ 156 | --username avnadmin 157 | ``` 158 | 159 | And retrieve the Apache Kafka Service URI with 160 | 161 | ```bash 162 | avn service get $KAFKA_SERVICE_NAME \ 163 | --project $PROJECT_NAME \ 164 | --format '{service_uri}' 165 | ``` 166 | 167 | The Apache Kafka Service URI is in the form `hostname:port` and provides the `hostname` and `port` needed to execute the code. 168 | You can wait for the newly created Apache Kafka instance to be ready with 169 | 170 | ```bash 171 | avn service wait $KAFKA_SERVICE_NAME --project $PROJECT_NAME 172 | ``` 173 | 174 | For a more detailed description of services and required credentials, check the [blog post](blogs.aiven.io) 175 | 176 | ## No Pizza? No Problem! 177 | 178 | The demo app produces pizza data, however is very simple to change the dataset produced to anything else. 179 | The code is based on [Faker](https://faker.readthedocs.io/en/master/), an Open Source Python library to generate fake data. 180 | 181 | To modify the data generated, change the `produce_pizza_order` function within the `main.py` file. The output of the function should be two python dictionaries, containing the event `key` and `message` 182 | 183 | ```python 184 | def produce_pizza_order (ordercount = 1): 185 | message = { 186 | 'name': fake.unique.name(), 187 | 'phoneNumber': fake.phone_number(), 188 | 'address': fake.address() 189 | } 190 | key = {'order' = ordercount} 191 | return message, key 192 | ``` 193 | 194 | To customise your dataset, you can check Faker's providers in the [related doc](https://faker.readthedocs.io/en/master/providers.html) 195 | 196 | **Edit**: 197 | Now with the ``subject`` parameter you can start generating: 198 | 199 | * fake `advancedmetric` data, for `100000` different hostname each having `30` different CPUs 200 | 201 | ``` 202 | Sending: {'hostname': 'hostname30692', 'cpu': 'cpu9', 'usage': 76.83123942281046, 'occurred_at': 1675064924126} 203 | Sending: {'hostname': 'hostname49005', 'cpu': 'cpu4', 'usage': 76.29121084860914, 'occurred_at': 1675064924126} 204 | Sending: {'hostname': 'hostname65485', 'cpu': 'cpu23', 'usage': 98.6179112244911, 'occurred_at': 1675064924126} 205 | Sending: {'hostname': 'hostname58818', 'cpu': 'cpu15', 'usage': 87.8367169647086, 'occurred_at': 1675064924126} 206 | ``` 207 | 208 | * fake `metric` data 209 | 210 | ``` 211 | {'hostname': 'grumpy', 'cpu': 'cpu4', 'usage': 85.2992318980445, 'occurred_at': 1634221377266} 212 | {'hostname': 'sleepy', 'cpu': 'cpu1', 'usage': 97.83137121091504, 'occurred_at': 1634221378192} 213 | {'hostname': 'sneezy', 'cpu': 'cpu3', 'usage': 85.36598989372837, 'occurred_at': 1634221378395} 214 | {'hostname': 'happy', 'cpu': 'cpu4', 'usage': 81.10449127622482, 'occurred_at': 1634221378800} 215 | {'hostname': 'dopey', 'cpu': 'cpu2', 'usage': 84.98778951073432, 'occurred_at': 1634221379306} 216 | ``` 217 | 218 | * fake `userbehaviour` data 219 | 220 | ``` 221 | {'user_id': 8, 'item_id': 25, 'behavior': 'buy', 'view_id': None, 'group_name': 'A', 'occurred_at': '2021-10-14 16:24:57'} 222 | {'user_id': 6, 'item_id': 28, 'behavior': 'buy', 'view_id': None, 'group_name': 'B', 'occurred_at': '2021-10-14 16:24:51'} 223 | {'user_id': 6, 'item_id': 23, 'behavior': 'cart', 'view_id': None, 'group_name': 'B', 'occurred_at': '2021-10-14 16:24:56'} 224 | {'user_id': 9, 'item_id': 26, 'behavior': 'buy', 'view_id': None, 'group_name': 'A', 'occurred_at': '2021-10-14 16:24:52'} 225 | {'user_id': 1, 'item_id': 23, 'behavior': 'buy', 'view_id': None, 'group_name': 'B', 'occurred_at': '2021-10-14 16:24:56'} 226 | ``` 227 | 228 | * fake `stock` data 229 | 230 | ``` 231 | {'stock_name': 'Pita Pan', 'stock_value': 11.311429500055635, 'timestamp': 1634221435718} 232 | {'stock_name': 'Deja Brew', 'stock_value': 9.956550461386884, 'timestamp': 1634221435877} 233 | {'stock_name': 'Thai Tanic', 'stock_value': 27.227119819515632, 'timestamp': 1634221436180} 234 | {'stock_name': 'Lawn & Order', 'stock_value': 20.625166423466904, 'timestamp': 1634221436285} 235 | {'stock_name': 'Indiana Jeans', 'stock_value': 24.598295127977412, 'timestamp': 1634221436491} 236 | ``` 237 | 238 | * real `realstock` data (based on yahoo finance apis) 239 | 240 | ``` 241 | {'stock_name': 'DOGE-USD', 'stock_value': 0.23705412447452545, 'timestamp': 1634221555719} 242 | {'stock_name': 'DOGE-USD', 'stock_value': 0.23705412447452545, 'timestamp': 1634221556098} 243 | {'stock_name': 'ETH-USD', 'stock_value': 3787.759521484375, 'timestamp': 1634221557011} 244 | {'stock_name': 'ETH-USD', 'stock_value': 3787.759521484375, 'timestamp': 1634221557493} 245 | {'stock_name': 'ADA-USD', 'stock_value': 2.2166504859924316, 'timestamp': 1634221557971} 246 | ``` 247 | 248 | Apache Kafka is either a registered trademark or trademark of the Apache Software Foundation in the United States and/or other countries. Aiven has no affiliation with and is not endorsed by The Apache Software Foundation. 249 | -------------------------------------------------------------------------------- /data_rolling.json: -------------------------------------------------------------------------------- 1 | [{"timestamp":1653,"value":"\u2800"},{"timestamp":1554,"value":"\u2800"},{"timestamp":416,"value":"\u2800"},{"timestamp":1210,"value":"\u2800"},{"timestamp":1373,"value":"\u28b8"},{"timestamp":1697,"value":"\u2800"},{"timestamp":964,"value":"\u28ff"},{"timestamp":708,"value":"\u28da"},{"timestamp":18,"value":"\u2800"},{"timestamp":1487,"value":"\u2800"},{"timestamp":1470,"value":"\u2800"},{"timestamp":774,"value":"\u2809"},{"timestamp":1289,"value":"\u2877"},{"timestamp":1331,"value":"\u2800"},{"timestamp":1423,"value":"\u2864"},{"timestamp":700,"value":"\u2840"},{"timestamp":973,"value":"\u2800"},{"timestamp":1493,"value":"\u2800"},{"timestamp":1481,"value":"\u2809"},{"timestamp":1699,"value":"\u2800"},{"timestamp":1685,"value":"\u2812"},{"timestamp":743,"value":"\u28ff"},{"timestamp":749,"value":"\u2800"},{"timestamp":710,"value":"\u285f"},{"timestamp":648,"value":"\u28ff"},{"timestamp":1263,"value":"\u2800"},{"timestamp":252,"value":"\u2800"},{"timestamp":1277,"value":"\u2800"},{"timestamp":88,"value":"\u287e"},{"timestamp":172,"value":"\u2800"},{"timestamp":223,"value":"\u28e4"},{"timestamp":1112,"value":"\u2800"},{"timestamp":13,"value":"\u2800"},{"timestamp":533,"value":"\u28ff"},{"timestamp":828,"value":"\u28bf"},{"timestamp":119,"value":"\u2800"},{"timestamp":1278,"value":"\u2800"},{"timestamp":220,"value":"\u28ff"},{"timestamp":668,"value":"\u2800"},{"timestamp":1254,"value":"\u285d"},{"timestamp":537,"value":"\u28e7"},{"timestamp":197,"value":"\u2800"},{"timestamp":1088,"value":"\u2800"},{"timestamp":1498,"value":"\u28f3"},{"timestamp":1375,"value":"\u28bf"},{"timestamp":522,"value":"\u28c0"},{"timestamp":189,"value":"\u2800"},{"timestamp":1591,"value":"\u2800"},{"timestamp":562,"value":"\u28ff"},{"timestamp":1520,"value":"\u2880"},{"timestamp":830,"value":"\u28d2"},{"timestamp":1639,"value":"\u2809"},{"timestamp":1134,"value":"\u28b8"},{"timestamp":846,"value":"\u2807"},{"timestamp":1322,"value":"\u2800"},{"timestamp":300,"value":"\u2800"},{"timestamp":216,"value":"\u2809"},{"timestamp":499,"value":"\u28ff"},{"timestamp":757,"value":"\u2818"},{"timestamp":591,"value":"\u28ff"},{"timestamp":1680,"value":"\u281b"},{"timestamp":1605,"value":"\u2800"},{"timestamp":272,"value":"\u2800"},{"timestamp":1590,"value":"\u2800"},{"timestamp":1693,"value":"\u2800"},{"timestamp":1611,"value":"\u2880"},{"timestamp":1704,"value":"\u2800"},{"timestamp":1453,"value":"\u28b8"},{"timestamp":1068,"value":"\u28db"},{"timestamp":1547,"value":"\u2800"},{"timestamp":1548,"value":"\u2800"},{"timestamp":341,"value":"\u2838"},{"timestamp":1038,"value":"\n"},{"timestamp":1285,"value":"\u2800"},{"timestamp":479,"value":"\u2800"},{"timestamp":842,"value":"\u28ff"},{"timestamp":1711,"value":":"},{"timestamp":788,"value":"\u2800"},{"timestamp":1398,"value":"\u28e4"},{"timestamp":1061,"value":"\u28c4"},{"timestamp":623,"value":"\u28ff"},{"timestamp":1282,"value":"\n"},{"timestamp":167,"value":"\u2800"},{"timestamp":1228,"value":"\u287f"},{"timestamp":8,"value":"\u2800"},{"timestamp":868,"value":"\u2800"},{"timestamp":52,"value":"\u2800"},{"timestamp":1726,"value":"4"},{"timestamp":130,"value":"\u2800"},{"timestamp":259,"value":"\u2800"},{"timestamp":192,"value":"\u2800"},{"timestamp":793,"value":"\u2800"},{"timestamp":217,"value":"\u2800"},{"timestamp":947,"value":"\u2832"},{"timestamp":775,"value":"\u283b"},{"timestamp":1180,"value":"\u2864"},{"timestamp":290,"value":"\u2800"},{"timestamp":134,"value":"\u2800"},{"timestamp":1396,"value":"\u28fe"},{"timestamp":940,"value":"\u2800"},{"timestamp":71,"value":"\u2800"},{"timestamp":995,"value":"\u2800"},{"timestamp":92,"value":"\u2800"},{"timestamp":848,"value":"\u2800"},{"timestamp":741,"value":"\u28ff"},{"timestamp":1105,"value":"\u28ff"},{"timestamp":364,"value":"\u2800"},{"timestamp":436,"value":"\u28ff"},{"timestamp":1303,"value":"\u2800"},{"timestamp":577,"value":"\u2800"},{"timestamp":505,"value":"\u28ff"},{"timestamp":582,"value":"\u28ff"},{"timestamp":1545,"value":"\u2800"},{"timestamp":1497,"value":"\u28c9"},{"timestamp":12,"value":"\u2800"},{"timestamp":870,"value":"\u28b0"},{"timestamp":806,"value":"\u2800"},{"timestamp":1058,"value":"\u2800"},{"timestamp":1151,"value":"\u2800"},{"timestamp":955,"value":"\u2838"},{"timestamp":1300,"value":"\u2800"},{"timestamp":1090,"value":"\u2800"},{"timestamp":702,"value":"\u2800"},{"timestamp":1571,"value":"\u2813"},{"timestamp":1521,"value":"\u28f0"},{"timestamp":1452,"value":"\u2800"},{"timestamp":1026,"value":"\u28ff"},{"timestamp":114,"value":"\u2800"},{"timestamp":1197,"value":"\u2807"},{"timestamp":1617,"value":"\u28c0"},{"timestamp":235,"value":"\u2800"},{"timestamp":1647,"value":"\u2800"},{"timestamp":11,"value":"\u2800"},{"timestamp":679,"value":"\u28ff"},{"timestamp":956,"value":"\u2843"},{"timestamp":1015,"value":"\u2800"},{"timestamp":1079,"value":"\u28b8"},{"timestamp":993,"value":"\u2808"},{"timestamp":1435,"value":"\u2857"},{"timestamp":1251,"value":"\u2800"},{"timestamp":1318,"value":"\u2807"},{"timestamp":748,"value":"\u2800"},{"timestamp":1410,"value":"\u2800"},{"timestamp":564,"value":"\u28ff"},{"timestamp":77,"value":"\u2800"},{"timestamp":704,"value":"\u2800"},{"timestamp":1449,"value":"\u2800"},{"timestamp":1356,"value":"\u2800"},{"timestamp":526,"value":"\u28ff"},{"timestamp":468,"value":"\u28ff"},{"timestamp":592,"value":"\u28ff"},{"timestamp":849,"value":"\u2800"},{"timestamp":1267,"value":"\u28ff"},{"timestamp":945,"value":"\u2849"},{"timestamp":133,"value":"\u2800"},{"timestamp":1084,"value":"\u28ff"},{"timestamp":768,"value":"\u28ff"},{"timestamp":1525,"value":"\u28f6"},{"timestamp":1621,"value":"\u28f7"},{"timestamp":392,"value":"\u2808"},{"timestamp":1478,"value":"\u28ff"},{"timestamp":379,"value":"\u28ff"},{"timestamp":1550,"value":"\u2800"},{"timestamp":202,"value":"\u2880"},{"timestamp":627,"value":"\u28ff"},{"timestamp":738,"value":"\u28ff"},{"timestamp":1052,"value":"\u2800"},{"timestamp":1530,"value":"\u2800"},{"timestamp":1535,"value":"\u2800"},{"timestamp":182,"value":"\u2800"},{"timestamp":1501,"value":"\u2800"},{"timestamp":1236,"value":"\u281b"},{"timestamp":1217,"value":"\u2800"},{"timestamp":1272,"value":"\u2800"},{"timestamp":1612,"value":"\u28c0"},{"timestamp":1466,"value":"\u2800"},{"timestamp":1269,"value":"\u2801"},{"timestamp":17,"value":"\u2800"},{"timestamp":1555,"value":"\u2800"},{"timestamp":513,"value":"\u28bf"},{"timestamp":560,"value":"\u28ff"},{"timestamp":1295,"value":"\u2800"},{"timestamp":426,"value":"\u2800"},{"timestamp":1227,"value":"\u28ff"},{"timestamp":616,"value":"\u28fe"},{"timestamp":705,"value":"\u28b8"},{"timestamp":1338,"value":"\u2800"},{"timestamp":1484,"value":"\u2800"},{"timestamp":937,"value":"\u2800"},{"timestamp":481,"value":"\u2800"},{"timestamp":201,"value":"\u2808"},{"timestamp":275,"value":"\u2800"},{"timestamp":265,"value":"\u28fe"},{"timestamp":139,"value":"\u2800"},{"timestamp":1553,"value":"\u2800"},{"timestamp":1288,"value":"\u28ff"},{"timestamp":1492,"value":"\u2800"},{"timestamp":672,"value":"\n"},{"timestamp":515,"value":"\u2800"},{"timestamp":565,"value":"\u28ff"},{"timestamp":1203,"value":"\u2800"},{"timestamp":318,"value":"\u28ff"},{"timestamp":418,"value":"\u2800"},{"timestamp":1353,"value":"\u2800"},{"timestamp":621,"value":"\u28ff"},{"timestamp":295,"value":"\u2800"},{"timestamp":475,"value":"\u28e6"},{"timestamp":1660,"value":"\u2800"},{"timestamp":760,"value":"\u28e4"},{"timestamp":1663,"value":"\u2812"},{"timestamp":792,"value":"\u2800"},{"timestamp":654,"value":"\u28ff"},{"timestamp":977,"value":"\n"},{"timestamp":1334,"value":"\u2880"},{"timestamp":1499,"value":"\u2800"},{"timestamp":1374,"value":"\u2864"},{"timestamp":310,"value":"\u2800"},{"timestamp":389,"value":"\u28ff"},{"timestamp":242,"value":"\u2800"},{"timestamp":1131,"value":"\u287f"},{"timestamp":47,"value":"\u2800"},{"timestamp":840,"value":"\u28ff"},{"timestamp":1533,"value":"\u2800"},{"timestamp":1086,"value":"\u28ff"},{"timestamp":1463,"value":"\u283d"},{"timestamp":58,"value":"\u2800"},{"timestamp":1569,"value":"\u2809"},{"timestamp":289,"value":"\u2800"},{"timestamp":283,"value":"\u28c5"},{"timestamp":771,"value":"\u2847"},{"timestamp":164,"value":"\u2800"},{"timestamp":331,"value":"\u28de"},{"timestamp":286,"value":"\u28f3"},{"timestamp":1136,"value":"\u28f0"},{"timestamp":1326,"value":"\u28fe"},{"timestamp":473,"value":"\u28ff"},{"timestamp":1689,"value":"\u2849"},{"timestamp":255,"value":"\u2800"},{"timestamp":1427,"value":"\u283f"},{"timestamp":1608,"value":"\u2800"},{"timestamp":1250,"value":"\u2800"},{"timestamp":918,"value":"\u28bb"},{"timestamp":178,"value":"\u2800"},{"timestamp":991,"value":"\u2800"},{"timestamp":1496,"value":"\u28fd"},{"timestamp":1179,"value":"\u28c0"},{"timestamp":801,"value":"\u28ff"},{"timestamp":983,"value":"\u28ff"},{"timestamp":1011,"value":"\u2808"},{"timestamp":873,"value":"\u2839"},{"timestamp":1183,"value":"\u2824"},{"timestamp":1721,"value":"."},{"timestamp":580,"value":"\u2800"},{"timestamp":98,"value":"\u2808"},{"timestamp":1691,"value":"\u2800"},{"timestamp":1119,"value":"\u2800"},{"timestamp":639,"value":"\u2800"},{"timestamp":1549,"value":"\u2800"},{"timestamp":1589,"value":"\u2800"},{"timestamp":942,"value":"\u2800"},{"timestamp":566,"value":"\u28ff"},{"timestamp":1420,"value":"\u2800"},{"timestamp":1264,"value":"\u2800"},{"timestamp":1661,"value":"\u2800"},{"timestamp":948,"value":"\u2836"},{"timestamp":184,"value":"\n"},{"timestamp":414,"value":"\u2800"},{"timestamp":170,"value":"\u2800"},{"timestamp":975,"value":"\u2800"},{"timestamp":116,"value":"\u2800"},{"timestamp":101,"value":"\u2800"},{"timestamp":1140,"value":"\u28b8"},{"timestamp":1732,"value":"a"},{"timestamp":207,"value":"\u2847"},{"timestamp":1047,"value":"\u2800"},{"timestamp":325,"value":"\u28ff"},{"timestamp":1074,"value":"\u2847"},{"timestamp":59,"value":"\u2800"},{"timestamp":1510,"value":"\u2800"},{"timestamp":681,"value":"\u28ff"},{"timestamp":194,"value":"\u2800"},{"timestamp":1517,"value":"\u2808"},{"timestamp":1400,"value":"\u28c4"},{"timestamp":535,"value":"\u28ff"},{"timestamp":780,"value":"\u28ff"},{"timestamp":1448,"value":"\u2800"},{"timestamp":1024,"value":"\u28ff"},{"timestamp":1460,"value":"\u28a0"},{"timestamp":1583,"value":"\u2811"},{"timestamp":833,"value":"\u2808"},{"timestamp":1232,"value":"\u281b"},{"timestamp":1409,"value":"\u2800"},{"timestamp":394,"value":"\u28e6"},{"timestamp":1477,"value":"\u28fe"},{"timestamp":1701,"value":"\u2800"},{"timestamp":445,"value":"\u28ff"},{"timestamp":111,"value":"\u2800"},{"timestamp":518,"value":"\u2800"},{"timestamp":1044,"value":"\u28ff"},{"timestamp":1321,"value":"\u2800"},{"timestamp":1390,"value":"\u2809"},{"timestamp":181,"value":"\u2800"},{"timestamp":530,"value":"\u28ff"},{"timestamp":1262,"value":"\u28b8"},{"timestamp":1667,"value":"\u2812"},{"timestamp":691,"value":"\u28b8"},{"timestamp":1407,"value":"\u2800"},{"timestamp":1010,"value":"\u2847"},{"timestamp":447,"value":"\u28ff"},{"timestamp":193,"value":"\u2800"},{"timestamp":1469,"value":"\u2800"},{"timestamp":925,"value":"\u2807"},{"timestamp":714,"value":"\u28ff"},{"timestamp":1538,"value":"\u2800"},{"timestamp":1730,"value":"x"},{"timestamp":1225,"value":"\u28fb"},{"timestamp":439,"value":"\u28ff"},{"timestamp":1376,"value":"\u285f"},{"timestamp":1454,"value":"\u2801"},{"timestamp":287,"value":"\u28a6"},{"timestamp":1208,"value":"\u28ff"},{"timestamp":501,"value":"\u28ff"},{"timestamp":628,"value":"\u28ff"},{"timestamp":1135,"value":"\u2847"},{"timestamp":1724,"value":"m"},{"timestamp":374,"value":"\u28e0"},{"timestamp":581,"value":"\u2800"},{"timestamp":1675,"value":"\u2800"},{"timestamp":1067,"value":"\u28df"},{"timestamp":1418,"value":"\u2800"},{"timestamp":1687,"value":"\u2809"},{"timestamp":1586,"value":"\u2809"},{"timestamp":1104,"value":"\u28ff"},{"timestamp":361,"value":"\u2800"},{"timestamp":1414,"value":"\u2800"},{"timestamp":635,"value":"\u28e7"},{"timestamp":589,"value":"\u28ff"},{"timestamp":752,"value":"\u2808"},{"timestamp":1369,"value":"\u28c4"},{"timestamp":196,"value":"\u2800"},{"timestamp":1391,"value":"\u281b"},{"timestamp":384,"value":"\u28ff"},{"timestamp":253,"value":"\u2800"},{"timestamp":85,"value":"\u2800"},{"timestamp":1170,"value":"\u2800"},{"timestamp":1450,"value":"\u2800"},{"timestamp":372,"value":"\u2800"},{"timestamp":305,"value":"\u2800"},{"timestamp":402,"value":"\u28e0"},{"timestamp":1089,"value":"\u2800"},{"timestamp":233,"value":"\u2800"},{"timestamp":128,"value":"\u2800"},{"timestamp":1194,"value":"\u283f"},{"timestamp":1290,"value":"\u280b"},{"timestamp":1377,"value":"\u2800"},{"timestamp":166,"value":"\u2800"},{"timestamp":550,"value":"\n"},{"timestamp":763,"value":"\u28fe"},{"timestamp":244,"value":"\u2800"},{"timestamp":739,"value":"\u28ff"},{"timestamp":1615,"value":"\u28c0"},{"timestamp":549,"value":"\u2800"},{"timestamp":1378,"value":"\u28bc"},{"timestamp":1695,"value":"\u2800"},{"timestamp":74,"value":"\u2800"},{"timestamp":759,"value":"\u28c0"},{"timestamp":645,"value":"\u28ff"},{"timestamp":247,"value":"\u2800"},{"timestamp":1080,"value":"\u2800"},{"timestamp":633,"value":"\u2800"},{"timestamp":1731,"value":"2"},{"timestamp":935,"value":"\u28b3"},{"timestamp":1380,"value":"\u2800"},{"timestamp":796,"value":"\u28f4"},{"timestamp":637,"value":"\u2844"},{"timestamp":1430,"value":"\u281b"},{"timestamp":1513,"value":"\u2800"},{"timestamp":556,"value":"\u28ff"},{"timestamp":461,"value":"\u2800"},{"timestamp":546,"value":"\u2800"},{"timestamp":179,"value":"\u2800"},{"timestamp":587,"value":"\u28ff"},{"timestamp":807,"value":"\u2800"},{"timestamp":145,"value":"\u2880"},{"timestamp":1093,"value":"\u2800"},{"timestamp":1181,"value":"\u2824"},{"timestamp":971,"value":"\u2800"},{"timestamp":811,"value":"\u2820"},{"timestamp":1095,"value":"\u2800"},{"timestamp":1332,"value":"\u2800"},{"timestamp":1040,"value":"\u28b8"},{"timestamp":1343,"value":"\n"},{"timestamp":211,"value":"\u2800"},{"timestamp":1111,"value":"\u2809"},{"timestamp":912,"value":"\u2800"},{"timestamp":1030,"value":"\u2800"},{"timestamp":1176,"value":"\u28ef"},{"timestamp":902,"value":"\u28ff"},{"timestamp":1221,"value":"\n"},{"timestamp":1065,"value":"\u2800"},{"timestamp":1446,"value":"\u2800"},{"timestamp":1147,"value":"\u28ff"},{"timestamp":326,"value":"\u28ff"},{"timestamp":711,"value":"\u28ff"},{"timestamp":1233,"value":"\u2809"},{"timestamp":1566,"value":"\u28b8"},{"timestamp":1019,"value":"\u2847"},{"timestamp":278,"value":"\u28c0"},{"timestamp":1431,"value":"\u2803"},{"timestamp":585,"value":"\u28ff"},{"timestamp":958,"value":"\u280f"},{"timestamp":726,"value":"\u2800"},{"timestamp":839,"value":"\u28ff"},{"timestamp":951,"value":"\u2847"},{"timestamp":55,"value":"\u2800"},{"timestamp":83,"value":"\u2800"},{"timestamp":1291,"value":"\u2800"},{"timestamp":269,"value":"\u2800"},{"timestamp":507,"value":"\u28ff"},{"timestamp":472,"value":"\u28ff"},{"timestamp":1442,"value":"\u28e4"},{"timestamp":607,"value":"\u2800"},{"timestamp":144,"value":"\u285a"},{"timestamp":87,"value":"\u28e4"},{"timestamp":386,"value":"\u28ff"},{"timestamp":783,"value":"\u28fd"},{"timestamp":625,"value":"\u28ff"},{"timestamp":198,"value":"\u2800"},{"timestamp":1519,"value":"\u2800"},{"timestamp":344,"value":"\u28ff"},{"timestamp":1403,"value":"\u2800"},{"timestamp":938,"value":"\u2800"},{"timestamp":1244,"value":"\u2800"},{"timestamp":117,"value":"\u2800"},{"timestamp":509,"value":"\u28ff"},{"timestamp":1081,"value":"\u2800"},{"timestamp":1717,"value":"y"},{"timestamp":349,"value":"\u28ff"},{"timestamp":779,"value":"\u28ff"},{"timestamp":1215,"value":"\u2800"},{"timestamp":1293,"value":"\u2800"},{"timestamp":634,"value":"\u2808"},{"timestamp":860,"value":"\u28ff"},{"timestamp":1599,"value":"\u2809"},{"timestamp":966,"value":"\u28ee"},{"timestamp":1050,"value":"\u28c6"},{"timestamp":291,"value":"\u2800"},{"timestamp":38,"value":"\u2800"},{"timestamp":773,"value":"\u2800"},{"timestamp":981,"value":"\u28ff"},{"timestamp":667,"value":"\u2800"},{"timestamp":78,"value":"\u2800"},{"timestamp":1325,"value":"\u28e0"},{"timestamp":854,"value":"\u2800"},{"timestamp":532,"value":"\u28ff"},{"timestamp":213,"value":"\u28c7"},{"timestamp":150,"value":"\u2800"},{"timestamp":1249,"value":"\u2800"},{"timestamp":46,"value":"\u2800"},{"timestamp":1069,"value":"\u28d3"},{"timestamp":435,"value":"\u28ff"},{"timestamp":903,"value":"\u28ff"},{"timestamp":707,"value":"\u28d3"},{"timestamp":650,"value":"\u28ff"},{"timestamp":1231,"value":"\u2816"},{"timestamp":608,"value":"\u2800"},{"timestamp":383,"value":"\u28ff"},{"timestamp":766,"value":"\u28f8"},{"timestamp":82,"value":"\u2800"},{"timestamp":1563,"value":"\u2800"},{"timestamp":776,"value":"\u28ff"},{"timestamp":1071,"value":"\u2847"},{"timestamp":1532,"value":"\u2800"},{"timestamp":614,"value":"\u2804"},{"timestamp":1025,"value":"\u28ff"},{"timestamp":123,"value":"\n"},{"timestamp":1034,"value":"\u2800"},{"timestamp":831,"value":"\u28f0"},{"timestamp":695,"value":"\u2800"},{"timestamp":658,"value":"\u28ff"},{"timestamp":889,"value":"\u28a0"},{"timestamp":480,"value":"\u2800"},{"timestamp":1696,"value":"\u2800"},{"timestamp":137,"value":"\u2800"},{"timestamp":1604,"value":"\u2800"},{"timestamp":40,"value":"\u2800"},{"timestamp":905,"value":"\u283e"},{"timestamp":476,"value":"\u2840"},{"timestamp":1062,"value":"\u2800"},{"timestamp":568,"value":"\u28ff"},{"timestamp":491,"value":"\u2800"},{"timestamp":1556,"value":"\u2800"},{"timestamp":1672,"value":"\u2809"},{"timestamp":1201,"value":"\u28b8"},{"timestamp":1489,"value":"\u2800"},{"timestamp":42,"value":"\u2800"},{"timestamp":306,"value":"\n"},{"timestamp":1344,"value":"\u2800"},{"timestamp":569,"value":"\u28ff"},{"timestamp":354,"value":"\u2800"},{"timestamp":1476,"value":"\u2812"},{"timestamp":408,"value":"\u28ff"},{"timestamp":1305,"value":"\u2800"},{"timestamp":1488,"value":"\u2800"},{"timestamp":745,"value":"\u2800"},{"timestamp":761,"value":"\u28ff"},{"timestamp":1237,"value":"\u2801"},{"timestamp":100,"value":"\u2800"},{"timestamp":907,"value":"\u2800"},{"timestamp":273,"value":"\u2880"},{"timestamp":1312,"value":"\u28c0"},{"timestamp":267,"value":"\u28ff"},{"timestamp":97,"value":"\u2800"},{"timestamp":525,"value":"\u28ff"},{"timestamp":433,"value":"\u28a0"},{"timestamp":640,"value":"\u2800"},{"timestamp":1308,"value":"\u2800"},{"timestamp":1618,"value":"\u28f8"},{"timestamp":1619,"value":"\u2802"},{"timestamp":1363,"value":"\u2800"},{"timestamp":477,"value":"\u2800"},{"timestamp":297,"value":"\u2800"},{"timestamp":1037,"value":"\u2800"},{"timestamp":1149,"value":"\u2800"},{"timestamp":618,"value":"\u28ff"},{"timestamp":1643,"value":"\u280b"},{"timestamp":446,"value":"\u28ff"},{"timestamp":857,"value":"\u28fc"},{"timestamp":1524,"value":"\u28dd"},{"timestamp":724,"value":"\u2800"},{"timestamp":1287,"value":"\u28bb"},{"timestamp":1212,"value":"\u2800"},{"timestamp":967,"value":"\u2801"},{"timestamp":694,"value":"\u2800"},{"timestamp":767,"value":"\u28ff"},{"timestamp":944,"value":"\u28c9"},{"timestamp":950,"value":"\u28b8"},{"timestamp":493,"value":"\u2800"},{"timestamp":1557,"value":"\u28b9"},{"timestamp":571,"value":"\u28ff"},{"timestamp":523,"value":"\u2840"},{"timestamp":1457,"value":"\u2801"},{"timestamp":1143,"value":"\u28bb"},{"timestamp":1175,"value":"\u28c0"},{"timestamp":517,"value":"\u2800"},{"timestamp":1306,"value":"\u2800"},{"timestamp":412,"value":"\u28ff"},{"timestamp":421,"value":"\u2800"},{"timestamp":678,"value":"\u28ff"},{"timestamp":567,"value":"\u28ff"},{"timestamp":825,"value":"\u28ff"},{"timestamp":1727,"value":"r"},{"timestamp":1479,"value":"\u28ff"},{"timestamp":693,"value":"\u2800"},{"timestamp":965,"value":"\u28ff"},{"timestamp":153,"value":"\u28c0"},{"timestamp":1543,"value":"\u2800"},{"timestamp":376,"value":"\u28ff"},{"timestamp":357,"value":"\u2800"},{"timestamp":348,"value":"\u28fe"},{"timestamp":1189,"value":"\u2801"},{"timestamp":534,"value":"\u28ff"},{"timestamp":1012,"value":"\u28b7"},{"timestamp":16,"value":"\u2800"},{"timestamp":603,"value":"\u2800"},{"timestamp":3,"value":"\u2800"},{"timestamp":1565,"value":"\u2800"},{"timestamp":420,"value":"\u2800"},{"timestamp":1669,"value":"\u2812"},{"timestamp":1330,"value":"\u2800"},{"timestamp":32,"value":"\u2836"},{"timestamp":859,"value":"\u28ff"},{"timestamp":200,"value":"\u2800"},{"timestamp":1646,"value":"\u2800"},{"timestamp":332,"value":"\u2849"},{"timestamp":28,"value":"\u28e0"},{"timestamp":932,"value":"\u28e7"},{"timestamp":881,"value":"\u2818"},{"timestamp":1459,"value":"\u2800"},{"timestamp":609,"value":"\u2800"},{"timestamp":680,"value":"\u28ff"},{"timestamp":274,"value":"\u28fc"},{"timestamp":1007,"value":"\u283d"},{"timestamp":990,"value":"\u2800"},{"timestamp":1464,"value":"\u28ff"},{"timestamp":301,"value":"\u2800"},{"timestamp":1206,"value":"\u28ff"},{"timestamp":795,"value":"\u2880"},{"timestamp":574,"value":"\u28af"},{"timestamp":596,"value":"\u28ff"},{"timestamp":81,"value":"\u2800"},{"timestamp":432,"value":"\u2800"},{"timestamp":1596,"value":"\u2800"},{"timestamp":952,"value":"\u2800"},{"timestamp":1004,"value":"\u2808"},{"timestamp":893,"value":"\u2800"},{"timestamp":1708,"value":"t"},{"timestamp":1076,"value":"\u28e0"},{"timestamp":1443,"value":"\u28c0"},{"timestamp":308,"value":"\u2800"},{"timestamp":879,"value":"\u2800"},{"timestamp":1601,"value":"\u28f8"},{"timestamp":921,"value":"\u28ff"},{"timestamp":696,"value":"\u28bb"},{"timestamp":1412,"value":"\u28a7"},{"timestamp":976,"value":"\u2800"},{"timestamp":288,"value":"\u28c4"},{"timestamp":54,"value":"\u2800"},{"timestamp":68,"value":"\u2800"},{"timestamp":292,"value":"\u2800"},{"timestamp":1059,"value":"\u2819"},{"timestamp":642,"value":"\u2800"},{"timestamp":1495,"value":"\u2839"},{"timestamp":299,"value":"\u2800"},{"timestamp":1451,"value":"\u2800"},{"timestamp":224,"value":"\u2800"},{"timestamp":165,"value":"\u2800"},{"timestamp":51,"value":"\u2800"},{"timestamp":284,"value":"\u28dc"},{"timestamp":395,"value":"\u2801"},{"timestamp":360,"value":"\u2800"},{"timestamp":1113,"value":"\u2800"},{"timestamp":1628,"value":"\u28c7"},{"timestamp":1165,"value":"\u28ee"},{"timestamp":261,"value":"\u28c4"},{"timestamp":110,"value":"\u2800"},{"timestamp":1372,"value":"\u2841"},{"timestamp":994,"value":"\u2847"},{"timestamp":1362,"value":"\u2800"},{"timestamp":218,"value":"\u2809"},{"timestamp":1670,"value":"\u2809"},{"timestamp":1167,"value":"\u28ff"},{"timestamp":1020,"value":"\u2838"},{"timestamp":1585,"value":"\u28ff"},{"timestamp":1676,"value":"\u2800"},{"timestamp":1659,"value":"\u2800"},{"timestamp":1097,"value":"\u2800"},{"timestamp":231,"value":"\u2800"},{"timestamp":36,"value":"\u28e4"},{"timestamp":121,"value":"\u2800"},{"timestamp":1370,"value":"\u285f"},{"timestamp":1348,"value":"\u2800"},{"timestamp":1424,"value":"\u2824"},{"timestamp":1259,"value":"\u2800"},{"timestamp":540,"value":"\u2800"},{"timestamp":404,"value":"\u28ff"},{"timestamp":832,"value":"\u2803"},{"timestamp":733,"value":"\n"},{"timestamp":674,"value":"\u2800"},{"timestamp":355,"value":"\u2800"},{"timestamp":1354,"value":"\u2800"},{"timestamp":1035,"value":"\u2800"},{"timestamp":548,"value":"\u2800"},{"timestamp":1640,"value":"\u2801"},{"timestamp":1725,"value":"\/"},{"timestamp":371,"value":"\u2800"},{"timestamp":910,"value":"\u2800"},{"timestamp":1357,"value":"\u2800"},{"timestamp":1055,"value":"\u285f"},{"timestamp":410,"value":"\u28ff"},{"timestamp":238,"value":"\u2800"},{"timestamp":328,"value":"\u28ff"},{"timestamp":875,"value":"\u2800"},{"timestamp":850,"value":"\u2800"},{"timestamp":1678,"value":"\u2808"},{"timestamp":1385,"value":"\u2800"},{"timestamp":1096,"value":"\u2800"},{"timestamp":1683,"value":"\u281f"},{"timestamp":999,"value":"\u2800"},{"timestamp":504,"value":"\u28ff"},{"timestamp":442,"value":"\u28ff"},{"timestamp":373,"value":"\u2800"},{"timestamp":1648,"value":"\n"},{"timestamp":195,"value":"\u2800"},{"timestamp":946,"value":"\u2812"},{"timestamp":459,"value":"\u2800"},{"timestamp":221,"value":"\u2842"},{"timestamp":1240,"value":"\u2800"},{"timestamp":688,"value":"\u2809"},{"timestamp":1379,"value":"\u2800"},{"timestamp":543,"value":"\u2800"},{"timestamp":1674,"value":"\u2809"},{"timestamp":1588,"value":"\u2800"},{"timestamp":1100,"value":"\u2820"},{"timestamp":1416,"value":"\u2800"},{"timestamp":1087,"value":"\u28ef"},{"timestamp":1186,"value":"\u2809"},{"timestamp":1733,"value":"n"},{"timestamp":1299,"value":"\u2800"},{"timestamp":41,"value":"\u2800"},{"timestamp":1060,"value":"\u2822"},{"timestamp":427,"value":"\u2800"},{"timestamp":555,"value":"\u28bb"},{"timestamp":1345,"value":"\u2800"},{"timestamp":1200,"value":"\u2800"},{"timestamp":598,"value":"\u28ff"},{"timestamp":34,"value":"\u2832"},{"timestamp":1258,"value":"\u2800"},{"timestamp":312,"value":"\u2800"},{"timestamp":1360,"value":"\u2800"},{"timestamp":1235,"value":"\u283d"},{"timestamp":14,"value":"\u2800"},{"timestamp":699,"value":"\u28a6"},{"timestamp":1511,"value":"\u2800"},{"timestamp":482,"value":"\u2800"},{"timestamp":1121,"value":"\u2800"},{"timestamp":329,"value":"\u2845"},{"timestamp":323,"value":"\u28ff"},{"timestamp":1421,"value":"\u2880"},{"timestamp":378,"value":"\u28ff"},{"timestamp":1688,"value":"\u2809"},{"timestamp":470,"value":"\u28ff"},{"timestamp":1284,"value":"\u2800"},{"timestamp":601,"value":"\u2800"},{"timestamp":1570,"value":"\u2809"},{"timestamp":808,"value":"\u2800"},{"timestamp":1196,"value":"\u28f7"},{"timestamp":471,"value":"\u28ff"},{"timestamp":1397,"value":"\u28e0"},{"timestamp":1625,"value":"\u2800"},{"timestamp":497,"value":"\u28ff"},{"timestamp":115,"value":"\u2800"},{"timestamp":786,"value":"\u2800"},{"timestamp":26,"value":"\u2800"},{"timestamp":163,"value":"\u2800"},{"timestamp":339,"value":"\u2836"},{"timestamp":781,"value":"\u28ff"},{"timestamp":895,"value":"\u2847"},{"timestamp":871,"value":"\u2840"},{"timestamp":1714,"value":"t"},{"timestamp":393,"value":"\u28f9"},{"timestamp":754,"value":"\u2800"},{"timestamp":1707,"value":"t"},{"timestamp":888,"value":"\u2847"},{"timestamp":1252,"value":"\u28db"},{"timestamp":1253,"value":"\u28cb"},{"timestamp":1694,"value":"\u2800"},{"timestamp":880,"value":"\u2800"},{"timestamp":254,"value":"\u2800"},{"timestamp":1433,"value":"\u28b3"},{"timestamp":1359,"value":"\u2800"},{"timestamp":1437,"value":"\u2847"},{"timestamp":551,"value":"\u2800"},{"timestamp":424,"value":"\u2800"},{"timestamp":336,"value":"\u2800"},{"timestamp":588,"value":"\u28ff"},{"timestamp":579,"value":"\u2800"},{"timestamp":171,"value":"\u2800"},{"timestamp":799,"value":"\u28ff"},{"timestamp":719,"value":"\u28ff"},{"timestamp":199,"value":"\u28e0"},{"timestamp":1561,"value":"\u28ff"},{"timestamp":1620,"value":"\u2810"},{"timestamp":1542,"value":"\u2800"},{"timestamp":1053,"value":"\u2800"},{"timestamp":1578,"value":"\u2813"},{"timestamp":666,"value":"\u2800"},{"timestamp":276,"value":"\u2800"},{"timestamp":1439,"value":"\u28f8"},{"timestamp":1632,"value":"\u2800"},{"timestamp":1001,"value":"\u2800"},{"timestamp":1003,"value":"\u2800"},{"timestamp":1057,"value":"\u2800"},{"timestamp":896,"value":"\u2800"},{"timestamp":1361,"value":"\u2800"},{"timestamp":578,"value":"\u2800"},{"timestamp":1091,"value":"\u2800"},{"timestamp":923,"value":"\u28ff"},{"timestamp":1,"value":"\n"},{"timestamp":1461,"value":"\u28de"},{"timestamp":1209,"value":"\u2803"},{"timestamp":53,"value":"\u2800"},{"timestamp":931,"value":"\u2800"},{"timestamp":1445,"value":"\u2847"},{"timestamp":1382,"value":"\u2800"},{"timestamp":1465,"value":"\n"},{"timestamp":1017,"value":"\u287f"},{"timestamp":1668,"value":"\u2812"},{"timestamp":1014,"value":"\u2807"},{"timestamp":230,"value":"\u2800"},{"timestamp":1313,"value":"\u28e0"},{"timestamp":44,"value":"\u2800"},{"timestamp":187,"value":"\u2800"},{"timestamp":143,"value":"\u28f4"},{"timestamp":57,"value":"\u2800"},{"timestamp":451,"value":"\u28ff"},{"timestamp":1124,"value":"\u28a6"},{"timestamp":1657,"value":"\u2800"},{"timestamp":506,"value":"\u28ff"},{"timestamp":968,"value":"\u2800"},{"timestamp":858,"value":"\u28ff"},{"timestamp":1395,"value":"\u28ab"},{"timestamp":845,"value":"\u28ff"},{"timestamp":385,"value":"\u28ff"},{"timestamp":1606,"value":"\u2800"},{"timestamp":338,"value":"\u28ad"},{"timestamp":1339,"value":"\u2800"},{"timestamp":1662,"value":"\u285b"},{"timestamp":147,"value":"\u280f"},{"timestamp":798,"value":"\u28ff"},{"timestamp":1594,"value":"\u2800"},{"timestamp":1712,"value":"\/"},{"timestamp":307,"value":"\u2800"},{"timestamp":1063,"value":"\u2800"},{"timestamp":122,"value":"\u2800"},{"timestamp":324,"value":"\u28ff"},{"timestamp":419,"value":"\u2800"},{"timestamp":69,"value":"\u2800"},{"timestamp":1480,"value":"\u284f"},{"timestamp":387,"value":"\u28ff"},{"timestamp":541,"value":"\u2800"},{"timestamp":91,"value":"\u2800"},{"timestamp":219,"value":"\u2809"},{"timestamp":271,"value":"\u2800"},{"timestamp":413,"value":"\u2824"},{"timestamp":1666,"value":"\u2812"},{"timestamp":335,"value":"\u2877"},{"timestamp":987,"value":"\u2808"},{"timestamp":901,"value":"\u28ff"},{"timestamp":320,"value":"\u28f6"},{"timestamp":1713,"value":"\/"},{"timestamp":496,"value":"\u28ff"},{"timestamp":894,"value":"\u2800"},{"timestamp":1033,"value":"\u2800"},{"timestamp":1592,"value":"\u2800"},{"timestamp":240,"value":"\u2800"},{"timestamp":33,"value":"\u2816"},{"timestamp":245,"value":"\n"},{"timestamp":1386,"value":"\u280b"},{"timestamp":343,"value":"\u28ff"},{"timestamp":1387,"value":"\u28b8"},{"timestamp":1320,"value":"\u2800"},{"timestamp":1054,"value":"\u2800"},{"timestamp":804,"value":"\u287f"},{"timestamp":434,"value":"\u28fc"},{"timestamp":511,"value":"\u28ff"},{"timestamp":1211,"value":"\u2800"},{"timestamp":396,"value":"\u2800"},{"timestamp":1518,"value":"\u2800"},{"timestamp":15,"value":"\u2800"},{"timestamp":784,"value":"\u28ff"},{"timestamp":974,"value":"\u2800"},{"timestamp":250,"value":"\u2800"},{"timestamp":6,"value":"\u2800"},{"timestamp":508,"value":"\u28ff"},{"timestamp":519,"value":"\u28c0"},{"timestamp":1214,"value":"\u2800"},{"timestamp":927,"value":"\u2800"},{"timestamp":1192,"value":"\u2812"},{"timestamp":1551,"value":"\u2800"},{"timestamp":1177,"value":"\u28c0"},{"timestamp":237,"value":"\u2800"},{"timestamp":169,"value":"\u2800"},{"timestamp":400,"value":"\u2800"},{"timestamp":1260,"value":"\u2800"},{"timestamp":744,"value":"\u284f"},{"timestamp":673,"value":"\u2800"},{"timestamp":1164,"value":"\u28ff"},{"timestamp":1241,"value":"\u2800"},{"timestamp":1399,"value":"\u28a4"},{"timestamp":819,"value":"\u2818"},{"timestamp":1226,"value":"\u28ff"},{"timestamp":1150,"value":"\u2800"},{"timestamp":1502,"value":"\u2800"},{"timestamp":1645,"value":"\u2800"},{"timestamp":1637,"value":"\u2809"},{"timestamp":1568,"value":"\u2803"},{"timestamp":531,"value":"\u28ff"},{"timestamp":820,"value":"\u28df"},{"timestamp":146,"value":"\u28fc"},{"timestamp":1650,"value":"\u2800"},{"timestamp":1458,"value":"\u2800"},{"timestamp":514,"value":"\u2847"},{"timestamp":979,"value":"\u28bf"},{"timestamp":302,"value":"\u2800"},{"timestamp":1456,"value":"\u28ff"},{"timestamp":1005,"value":"\u28e7"},{"timestamp":762,"value":"\u2836"},{"timestamp":1157,"value":"\u2800"},{"timestamp":260,"value":"\u2801"},{"timestamp":1541,"value":"\u2847"},{"timestamp":1434,"value":"\u2840"},{"timestamp":638,"value":"\u2800"},{"timestamp":812,"value":"\u2856"},{"timestamp":148,"value":"\u2800"},{"timestamp":669,"value":"\u2800"},{"timestamp":398,"value":"\u2800"},{"timestamp":1429,"value":"\u281b"},{"timestamp":1364,"value":"\u2800"},{"timestamp":212,"value":"\u2800"},{"timestamp":1595,"value":"\u2800"},{"timestamp":73,"value":"\u2800"},{"timestamp":366,"value":"\u2800"},{"timestamp":467,"value":"\u28ff"},{"timestamp":1158,"value":"\u2800"},{"timestamp":1654,"value":"\u2800"},{"timestamp":1187,"value":"\u28ff"},{"timestamp":108,"value":"\u2800"},{"timestamp":1008,"value":"\u283f"},{"timestamp":1168,"value":"\u2847"},{"timestamp":1169,"value":"\u2800"},{"timestamp":49,"value":"\u2800"},{"timestamp":342,"value":"\u28ff"},{"timestamp":1582,"value":"\u28ff"},{"timestamp":1298,"value":"\u2800"},{"timestamp":782,"value":"\u28ff"},{"timestamp":452,"value":"\u28ff"},{"timestamp":657,"value":"\u28ff"},{"timestamp":1347,"value":"\u2800"},{"timestamp":1636,"value":"\u2808"},{"timestamp":80,"value":"\u2800"},{"timestamp":872,"value":"\u2800"},{"timestamp":1720,"value":"l"},{"timestamp":1677,"value":"\u2800"},{"timestamp":906,"value":"\u28ff"},{"timestamp":1723,"value":"o"},{"timestamp":56,"value":"\u2800"},{"timestamp":1107,"value":"\u2847"},{"timestamp":1602,"value":"\u2800"},{"timestamp":814,"value":"\u2809"},{"timestamp":690,"value":"\u2800"},{"timestamp":492,"value":"\u2800"},{"timestamp":1036,"value":"\u2800"},{"timestamp":158,"value":"\u2800"},{"timestamp":1319,"value":"\u2800"},{"timestamp":1137,"value":"\u280b"},{"timestamp":924,"value":"\u28ff"},{"timestamp":39,"value":"\u2800"},{"timestamp":900,"value":"\u28ff"},{"timestamp":1336,"value":"\u2800"},{"timestamp":1365,"value":"\u2820"},{"timestamp":462,"value":"\u28a4"},{"timestamp":1219,"value":"\u2800"},{"timestamp":1114,"value":"\u2800"},{"timestamp":957,"value":"\u28a0"},{"timestamp":697,"value":"\u2800"},{"timestamp":409,"value":"\u28ff"},{"timestamp":257,"value":"\u2884"},{"timestamp":573,"value":"\u28bb"},{"timestamp":1392,"value":"\u2832"},{"timestamp":885,"value":"\u2836"},{"timestamp":855,"value":"\n"},{"timestamp":227,"value":"\u2800"},{"timestamp":1327,"value":"\u28ff"},{"timestamp":916,"value":"\n"},{"timestamp":913,"value":"\u2800"},{"timestamp":817,"value":"\u2800"},{"timestamp":127,"value":"\u2800"},{"timestamp":816,"value":"\u2800"},{"timestamp":986,"value":"\u2800"},{"timestamp":1204,"value":"\u2838"},{"timestamp":277,"value":"\u2880"},{"timestamp":417,"value":"\u2800"},{"timestamp":1337,"value":"\u2800"},{"timestamp":263,"value":"\u28fe"},{"timestamp":1122,"value":"\u2808"},{"timestamp":1656,"value":"\u2800"},{"timestamp":629,"value":"\u28ff"},{"timestamp":605,"value":"\u2800"},{"timestamp":248,"value":"\u2800"},{"timestamp":401,"value":"\u28e4"},{"timestamp":1116,"value":"\u2803"},{"timestamp":1078,"value":"\u2800"},{"timestamp":837,"value":"\u28ff"},{"timestamp":1503,"value":"\u283f"},{"timestamp":1163,"value":"\u28e8"},{"timestamp":1056,"value":"\u2800"},{"timestamp":96,"value":"\u2800"},{"timestamp":919,"value":"\u28ff"},{"timestamp":890,"value":"\u284f"},{"timestamp":1156,"value":"\u2800"},{"timestamp":1471,"value":"\u2800"},{"timestamp":865,"value":"\u283f"},{"timestamp":1118,"value":"\u2800"},{"timestamp":709,"value":"\u287a"},{"timestamp":160,"value":"\u287f"},{"timestamp":1173,"value":"\u28c0"},{"timestamp":963,"value":"\u28ff"},{"timestamp":1729,"value":"e"},{"timestamp":1627,"value":"\u2808"},{"timestamp":1166,"value":"\u28ff"},{"timestamp":653,"value":"\u28ff"},{"timestamp":737,"value":"\u28ff"},{"timestamp":138,"value":"\u2800"},{"timestamp":1152,"value":"\u2800"},{"timestamp":611,"value":"\n"},{"timestamp":644,"value":"\u28af"},{"timestamp":1310,"value":"\u2880"},{"timestamp":113,"value":"\u2800"},{"timestamp":698,"value":"\u2819"},{"timestamp":930,"value":"\u2800"},{"timestamp":490,"value":"\u2800"},{"timestamp":90,"value":"\u2800"},{"timestamp":309,"value":"\u2800"},{"timestamp":1631,"value":"\u2800"},{"timestamp":1473,"value":"\u2808"},{"timestamp":1658,"value":"\u2800"},{"timestamp":24,"value":"\u2800"},{"timestamp":863,"value":"\u28ff"},{"timestamp":1575,"value":"\u28c4"},{"timestamp":1296,"value":"\u2800"},{"timestamp":246,"value":"\u2800"},{"timestamp":1276,"value":"\u2800"},{"timestamp":1573,"value":"\u2822"},{"timestamp":140,"value":"\u2880"},{"timestamp":1220,"value":"\u2800"},{"timestamp":1245,"value":"\u2800"},{"timestamp":926,"value":"\u28b8"},{"timestamp":703,"value":"\u287c"},{"timestamp":423,"value":"\u2800"},{"timestamp":790,"value":"\u2800"},{"timestamp":1172,"value":"\u2880"},{"timestamp":980,"value":"\u28ff"},{"timestamp":455,"value":"\u28e4"},{"timestamp":1255,"value":"\u2800"},{"timestamp":576,"value":"\u2800"},{"timestamp":953,"value":"\u2847"},{"timestamp":1641,"value":"\u2800"},{"timestamp":131,"value":"\u2800"},{"timestamp":663,"value":"\u2800"},{"timestamp":1419,"value":"\u2800"},{"timestamp":1505,"value":"\u28b9"},{"timestamp":789,"value":"\u2800"},{"timestamp":720,"value":"\u28ff"},{"timestamp":1665,"value":"\u2812"},{"timestamp":1567,"value":"\u285f"},{"timestamp":1218,"value":"\u2800"},{"timestamp":206,"value":"\u28ff"},{"timestamp":1141,"value":"\u2800"},{"timestamp":727,"value":"\u2800"},{"timestamp":586,"value":"\u28ff"},{"timestamp":1352,"value":"\u2800"},{"timestamp":1598,"value":"\u2800"},{"timestamp":512,"value":"\u28ff"},{"timestamp":769,"value":"\u28ff"},{"timestamp":1115,"value":"\u28f8"},{"timestamp":604,"value":"\u2800"},{"timestamp":229,"value":"\u2800"},{"timestamp":1690,"value":"\u2800"},{"timestamp":1623,"value":"\u2800"},{"timestamp":1577,"value":"\u28cd"},{"timestamp":1642,"value":"\u2808"},{"timestamp":1162,"value":"\u2800"},{"timestamp":1682,"value":"\u283f"},{"timestamp":333,"value":"\u28b3"},{"timestamp":1358,"value":"\u2800"},{"timestamp":843,"value":"\u28ff"},{"timestamp":728,"value":"\u2800"},{"timestamp":1509,"value":"\u2840"},{"timestamp":397,"value":"\u2800"},{"timestamp":109,"value":"\u2800"},{"timestamp":862,"value":"\u28ff"},{"timestamp":1223,"value":"\u2800"},{"timestamp":1281,"value":"\u2800"},{"timestamp":7,"value":"\u2800"},{"timestamp":1406,"value":"\u2800"},{"timestamp":1185,"value":"\u281b"},{"timestamp":23,"value":"\u2800"},{"timestamp":315,"value":"\u28e0"},{"timestamp":450,"value":"\u28ff"},{"timestamp":1455,"value":"\u2800"},{"timestamp":1649,"value":"\u2800"},{"timestamp":878,"value":"\u2800"},{"timestamp":1261,"value":"\u2800"},{"timestamp":915,"value":"\u2800"},{"timestamp":867,"value":"\u2800"},{"timestamp":105,"value":"\u2800"},{"timestamp":941,"value":"\u2800"},{"timestamp":813,"value":"\u280b"},{"timestamp":363,"value":"\u2800"},{"timestamp":1516,"value":"\u2840"},{"timestamp":345,"value":"\u28ff"},{"timestamp":1491,"value":"\u2800"},{"timestamp":1393,"value":"\u28e4"},{"timestamp":1266,"value":"\u28ff"},{"timestamp":887,"value":"\u283d"},{"timestamp":298,"value":"\u2800"},{"timestamp":314,"value":"\u2800"},{"timestamp":159,"value":"\u28f4"},{"timestamp":770,"value":"\u2847"},{"timestamp":48,"value":"\u2800"},{"timestamp":1425,"value":"\u2824"},{"timestamp":350,"value":"\u28df"},{"timestamp":1174,"value":"\u28c0"},{"timestamp":330,"value":"\u28f0"},{"timestamp":1474,"value":"\u281b"},{"timestamp":1314,"value":"\u28fc"},{"timestamp":712,"value":"\u28ff"},{"timestamp":536,"value":"\u28ff"},{"timestamp":141,"value":"\u2824"},{"timestamp":1638,"value":"\u2809"},{"timestamp":1110,"value":"\u2809"},{"timestamp":992,"value":"\u2800"},{"timestamp":1018,"value":"\u2808"},{"timestamp":236,"value":"\u2800"},{"timestamp":684,"value":"\u28ff"},{"timestamp":908,"value":"\u2800"},{"timestamp":1051,"value":"\u2800"},{"timestamp":655,"value":"\u28ff"},{"timestamp":706,"value":"\u28ff"},{"timestamp":262,"value":"\u28e2"},{"timestamp":1161,"value":"\u2800"},{"timestamp":1350,"value":"\u28b7"},{"timestamp":1718,"value":"u"},{"timestamp":95,"value":"\u2800"},{"timestamp":258,"value":"\u2840"},{"timestamp":1559,"value":"\u283d"},{"timestamp":280,"value":"\u28c0"},{"timestamp":619,"value":"\u28ff"},{"timestamp":1607,"value":"\u2800"},{"timestamp":692,"value":"\u2840"},{"timestamp":646,"value":"\u28ff"},{"timestamp":810,"value":"\u2800"},{"timestamp":1438,"value":"\u2800"},{"timestamp":93,"value":"\u2800"},{"timestamp":852,"value":"\u2800"},{"timestamp":204,"value":"\u289e"},{"timestamp":1023,"value":"\u28ff"},{"timestamp":63,"value":"\u2800"},{"timestamp":453,"value":"\u2877"},{"timestamp":1686,"value":"\u281a"},{"timestamp":1006,"value":"\u2809"},{"timestamp":1145,"value":"\u28ff"},{"timestamp":430,"value":"\u2800"},{"timestamp":972,"value":"\u2800"},{"timestamp":713,"value":"\u28ff"},{"timestamp":1367,"value":"\u2864"},{"timestamp":787,"value":"\u2800"},{"timestamp":751,"value":"\u2800"},{"timestamp":494,"value":"\u28fe"},{"timestamp":1679,"value":"\u2899"},{"timestamp":391,"value":"\u28ff"},{"timestamp":701,"value":"\u2800"},{"timestamp":851,"value":"\u2800"},{"timestamp":209,"value":"\u2800"},{"timestamp":346,"value":"\u28ff"},{"timestamp":864,"value":"\u28ff"},{"timestamp":225,"value":"\u2800"},{"timestamp":1528,"value":"\u2800"},{"timestamp":1191,"value":"\u2838"},{"timestamp":226,"value":"\u2800"},{"timestamp":347,"value":"\u28ff"},{"timestamp":1417,"value":"\u2800"},{"timestamp":1432,"value":"\u2800"},{"timestamp":615,"value":"\u28f2"},{"timestamp":747,"value":"\u2800"},{"timestamp":1108,"value":"\u2800"},{"timestamp":465,"value":"\u28ff"},{"timestamp":750,"value":"\u2800"},{"timestamp":1048,"value":"\u2800"},{"timestamp":1534,"value":"\u2800"},{"timestamp":821,"value":"\u2833"},{"timestamp":1536,"value":"\u2800"},{"timestamp":294,"value":"\u2800"},{"timestamp":909,"value":"\u2800"},{"timestamp":1634,"value":"\u2800"},{"timestamp":89,"value":"\u2803"},{"timestamp":933,"value":"\u2800"},{"timestamp":652,"value":"\u28ff"},{"timestamp":823,"value":"\u28dd"},{"timestamp":772,"value":"\u28b8"},{"timestamp":1600,"value":"\u2800"},{"timestamp":368,"value":"\u2800"},{"timestamp":1468,"value":"\u2800"},{"timestamp":641,"value":"\u2800"},{"timestamp":1301,"value":"\u2800"},{"timestamp":661,"value":"\u28ff"},{"timestamp":1540,"value":"\u28ff"},{"timestamp":510,"value":"\u28ff"},{"timestamp":1146,"value":"\u28ff"},{"timestamp":483,"value":"\u2800"},{"timestamp":802,"value":"\u28ff"},{"timestamp":1587,"value":"\n"},{"timestamp":22,"value":"\u2800"},{"timestamp":1700,"value":"\u2800"},{"timestamp":1198,"value":"\u2800"},{"timestamp":613,"value":"\u2800"},{"timestamp":1257,"value":"\u2847"},{"timestamp":1000,"value":"\u2800"},{"timestamp":185,"value":"\u2800"},{"timestamp":1405,"value":"\u2800"},{"timestamp":282,"value":"\u28f7"},{"timestamp":1626,"value":"\u2800"},{"timestamp":1341,"value":"\u2800"},{"timestamp":125,"value":"\u2800"},{"timestamp":157,"value":"\u28c0"},{"timestamp":597,"value":"\u28ff"},{"timestamp":1031,"value":"\u2800"},{"timestamp":594,"value":"\u28ff"},{"timestamp":853,"value":"\u2800"},{"timestamp":1655,"value":"\u2800"},{"timestamp":175,"value":"\u2800"},{"timestamp":1529,"value":"\u2800"},{"timestamp":1722,"value":"c"},{"timestamp":794,"value":"\n"},{"timestamp":2,"value":"\u2800"},{"timestamp":214,"value":"\u2808"},{"timestamp":527,"value":"\u28ff"},{"timestamp":869,"value":"\u2800"},{"timestamp":1022,"value":"\u28ff"},{"timestamp":183,"value":"\u2800"},{"timestamp":1515,"value":"\u28c4"},{"timestamp":239,"value":"\u2800"},{"timestamp":882,"value":"\u28d7"},{"timestamp":303,"value":"\u2800"},{"timestamp":334,"value":"\u28e4"},{"timestamp":1032,"value":"\u2800"},{"timestamp":716,"value":"\u28ff"},{"timestamp":683,"value":"\u28ff"},{"timestamp":809,"value":"\u2800"},{"timestamp":815,"value":"\u2800"},{"timestamp":687,"value":"\u280b"},{"timestamp":791,"value":"\u2800"},{"timestamp":152,"value":"\u28c0"},{"timestamp":1610,"value":"\u2800"},{"timestamp":1349,"value":"\u2818"},{"timestamp":561,"value":"\u28ff"},{"timestamp":232,"value":"\u2800"},{"timestamp":984,"value":"\u28ff"},{"timestamp":425,"value":"\u2800"},{"timestamp":1544,"value":"\u2800"},{"timestamp":356,"value":"\u2800"},{"timestamp":327,"value":"\u28ff"},{"timestamp":186,"value":"\u2800"},{"timestamp":359,"value":"\u2800"},{"timestamp":268,"value":"\u2847"},{"timestamp":765,"value":"\u2800"},{"timestamp":1413,"value":"\u2840"},{"timestamp":928,"value":"\u2800"},{"timestamp":489,"value":"\n"},{"timestamp":180,"value":"\u2800"},{"timestamp":631,"value":"\u280b"},{"timestamp":1027,"value":"\u2819"},{"timestamp":1616,"value":"\u28e0"},{"timestamp":1564,"value":"\u2800"},{"timestamp":521,"value":"\u28c0"},{"timestamp":1139,"value":"\u2800"},{"timestamp":1028,"value":"\u2800"},{"timestamp":1283,"value":"\u2800"},{"timestamp":682,"value":"\u28ff"},{"timestamp":554,"value":"\u28fe"},{"timestamp":665,"value":"\u2800"},{"timestamp":1644,"value":"\u2800"},{"timestamp":380,"value":"\u28ff"},{"timestamp":151,"value":"\u2800"},{"timestamp":1092,"value":"\u2800"},{"timestamp":99,"value":"\u28e7"},{"timestamp":415,"value":"\u2800"},{"timestamp":365,"value":"\u2800"},{"timestamp":1366,"value":"\u28e4"},{"timestamp":689,"value":"\u2801"},{"timestamp":723,"value":"\u28e7"},{"timestamp":959,"value":"\u28fb"},{"timestamp":129,"value":"\u2800"},{"timestamp":520,"value":"\u28c0"},{"timestamp":1558,"value":"\u282d"},{"timestamp":407,"value":"\u28ff"},{"timestamp":486,"value":"\u2800"},{"timestamp":649,"value":"\u28ff"},{"timestamp":104,"value":"\u2800"},{"timestamp":1651,"value":"\u2800"},{"timestamp":827,"value":"\u2803"},{"timestamp":542,"value":"\u2800"},{"timestamp":1494,"value":"\u2800"},{"timestamp":118,"value":"\u2800"},{"timestamp":1716,"value":"n"},{"timestamp":647,"value":"\u28ff"},{"timestamp":75,"value":"\u2800"},{"timestamp":1129,"value":"\u28ff"},{"timestamp":478,"value":"\u2800"},{"timestamp":736,"value":"\u28fb"},{"timestamp":205,"value":"\u28c1"},{"timestamp":1234,"value":"\u28e9"},{"timestamp":844,"value":"\u287f"},{"timestamp":595,"value":"\u28ff"},{"timestamp":448,"value":"\u28ff"},{"timestamp":538,"value":"\u2800"},{"timestamp":428,"value":"\n"},{"timestamp":883,"value":"\u2812"},{"timestamp":1274,"value":"\u2800"},{"timestamp":1159,"value":"\u2800"},{"timestamp":1043,"value":"\u28ff"},{"timestamp":441,"value":"\u28ff"},{"timestamp":659,"value":"\u28ff"},{"timestamp":1083,"value":"\u28ff"},{"timestamp":1444,"value":"\u2880"},{"timestamp":352,"value":"\u2800"},{"timestamp":1333,"value":"\u2800"},{"timestamp":1202,"value":"\u2800"},{"timestamp":60,"value":"\u2800"},{"timestamp":31,"value":"\u2836"},{"timestamp":803,"value":"\u28ff"},{"timestamp":1706,"value":"h"},{"timestamp":498,"value":"\u28ff"},{"timestamp":1609,"value":"\u2800"},{"timestamp":572,"value":"\u281f"},{"timestamp":66,"value":"\u2800"},{"timestamp":922,"value":"\u28ff"},{"timestamp":934,"value":"\u2800"},{"timestamp":1270,"value":"\u2800"},{"timestamp":437,"value":"\u28ff"},{"timestamp":120,"value":"\u2800"},{"timestamp":717,"value":"\u28ff"},{"timestamp":1475,"value":"\u2812"},{"timestamp":1213,"value":"\u2800"},{"timestamp":411,"value":"\u28ff"},{"timestamp":454,"value":"\u28ed"},{"timestamp":1436,"value":"\u2832"},{"timestamp":321,"value":"\u28ff"},{"timestamp":1371,"value":"\u28af"},{"timestamp":1242,"value":"\u2800"},{"timestamp":1049,"value":"\u2818"},{"timestamp":313,"value":"\u2800"},{"timestamp":612,"value":"\u2800"},{"timestamp":1246,"value":"\u2800"},{"timestamp":37,"value":"\u28c0"},{"timestamp":135,"value":"\u2800"},{"timestamp":340,"value":"\u2836"},{"timestamp":285,"value":"\u28ee"},{"timestamp":978,"value":"\u2800"},{"timestamp":1441,"value":"\u2800"},{"timestamp":1514,"value":"\u28b8"},{"timestamp":557,"value":"\u28ff"},{"timestamp":805,"value":"\u2800"},{"timestamp":1039,"value":"\u2800"},{"timestamp":675,"value":"\u28a0"},{"timestamp":281,"value":"\u28f9"},{"timestamp":1106,"value":"\u28ff"},{"timestamp":191,"value":"\u2800"},{"timestamp":985,"value":"\u28ff"},{"timestamp":722,"value":"\u28ff"},{"timestamp":1579,"value":"\u28f2"},{"timestamp":1630,"value":"\u2800"},{"timestamp":1574,"value":"\u2824"},{"timestamp":460,"value":"\u2800"},{"timestamp":998,"value":"\u2840"},{"timestamp":1297,"value":"\u2800"},{"timestamp":1009,"value":"\u28fa"},{"timestamp":1633,"value":"\u2800"},{"timestamp":1389,"value":"\u2800"},{"timestamp":626,"value":"\u28ff"},{"timestamp":929,"value":"\u2800"},{"timestamp":1029,"value":"\u2800"},{"timestamp":249,"value":"\u2800"},{"timestamp":1546,"value":"\u2800"},{"timestamp":102,"value":"\u2800"},{"timestamp":1309,"value":"\u2847"},{"timestamp":740,"value":"\u28ff"},{"timestamp":296,"value":"\u2800"},{"timestamp":936,"value":"\u2840"},{"timestamp":1381,"value":"\u2800"},{"timestamp":1155,"value":"\u2800"},{"timestamp":243,"value":"\u2800"},{"timestamp":1222,"value":"\u2800"},{"timestamp":1195,"value":"\u28bf"},{"timestamp":1045,"value":"\u28ff"},{"timestamp":826,"value":"\u28bf"},{"timestamp":464,"value":"\u28ff"},{"timestamp":1462,"value":"\u28ef"},{"timestamp":1702,"value":"\u2800"},{"timestamp":270,"value":"\u2800"},{"timestamp":72,"value":"\u2800"},{"timestamp":390,"value":"\u28ff"},{"timestamp":149,"value":"\u2800"},{"timestamp":251,"value":"\u2800"},{"timestamp":1440,"value":"\u2800"},{"timestamp":488,"value":"\u2800"},{"timestamp":1268,"value":"\u285f"},{"timestamp":228,"value":"\u2800"},{"timestamp":718,"value":"\u28ff"},{"timestamp":1304,"value":"\u2800"},{"timestamp":126,"value":"\u2800"},{"timestamp":358,"value":"\u2800"},{"timestamp":1130,"value":"\u28ff"},{"timestamp":62,"value":"\n"},{"timestamp":841,"value":"\u28ff"},{"timestamp":884,"value":"\u2836"},{"timestamp":662,"value":"\u2841"},{"timestamp":996,"value":"\u2800"},{"timestamp":528,"value":"\u28ff"},{"timestamp":1671,"value":"\u2809"},{"timestamp":1127,"value":"\u2800"},{"timestamp":1109,"value":"\u2800"},{"timestamp":469,"value":"\u28ff"},{"timestamp":622,"value":"\u28ff"},{"timestamp":1064,"value":"\u2800"},{"timestamp":1125,"value":"\u28c4"},{"timestamp":899,"value":"\u28ff"},{"timestamp":449,"value":"\u28ff"},{"timestamp":1133,"value":"\u28c0"},{"timestamp":606,"value":"\u2800"},{"timestamp":721,"value":"\u28ff"},{"timestamp":1426,"value":"\u2824"},{"timestamp":1271,"value":"\u2800"},{"timestamp":1705,"value":"\n"},{"timestamp":406,"value":"\u28ff"},{"timestamp":1275,"value":"\u2800"},{"timestamp":1635,"value":"\u2800"},{"timestamp":370,"value":"\u2800"},{"timestamp":1199,"value":"\u2800"},{"timestamp":136,"value":"\u2800"},{"timestamp":500,"value":"\u28ff"},{"timestamp":316,"value":"\u28fc"},{"timestamp":1073,"value":"\u28b8"},{"timestamp":824,"value":"\u28f6"},{"timestamp":886,"value":"\u283e"},{"timestamp":1622,"value":"\u28bb"},{"timestamp":458,"value":"\u2800"},{"timestamp":834,"value":"\u2846"},{"timestamp":651,"value":"\u28ff"},{"timestamp":539,"value":"\u2800"},{"timestamp":162,"value":"\u2800"},{"timestamp":610,"value":"\u2800"},{"timestamp":1238,"value":"\u2800"},{"timestamp":1066,"value":"\u2839"},{"timestamp":1483,"value":"\u2801"},{"timestamp":107,"value":"\u2800"},{"timestamp":1482,"value":"\u2809"},{"timestamp":1126,"value":"\u2840"},{"timestamp":1230,"value":"\u2864"},{"timestamp":1098,"value":"\u2800"},{"timestamp":1265,"value":"\u2800"},{"timestamp":1504,"value":"\u283e"},{"timestamp":1072,"value":"\u2800"},{"timestamp":1710,"value":"s"},{"timestamp":94,"value":"\u2800"},{"timestamp":279,"value":"\u28c0"},{"timestamp":1539,"value":"\u2819"},{"timestamp":1351,"value":"\u2840"},{"timestamp":1046,"value":"\u28ff"},{"timestamp":84,"value":"\u2800"},{"timestamp":917,"value":"\u2800"},{"timestamp":234,"value":"\u2800"},{"timestamp":1323,"value":"\u287c"},{"timestamp":785,"value":"\u2846"},{"timestamp":1581,"value":"\u28ae"},{"timestamp":1328,"value":"\u28ff"},{"timestamp":155,"value":"\u2880"},{"timestamp":636,"value":"\u2833"},{"timestamp":777,"value":"\u28ff"},{"timestamp":1188,"value":"\u280b"},{"timestamp":989,"value":"\u2800"},{"timestamp":836,"value":"\u28b8"},{"timestamp":600,"value":"\u28c4"},{"timestamp":715,"value":"\u28ff"},{"timestamp":304,"value":"\u2800"},{"timestamp":1383,"value":"\u2800"},{"timestamp":818,"value":"\u2800"},{"timestamp":552,"value":"\u2800"},{"timestamp":756,"value":"\u2800"},{"timestamp":1703,"value":"\u2800"},{"timestamp":176,"value":"\u2800"},{"timestamp":1527,"value":"\u2800"},{"timestamp":911,"value":"\u2800"},{"timestamp":377,"value":"\u28ff"},{"timestamp":1486,"value":"\u2800"},{"timestamp":322,"value":"\u28ff"},{"timestamp":545,"value":"\u2800"},{"timestamp":1340,"value":"\u2800"},{"timestamp":1132,"value":"\u28c7"},{"timestamp":381,"value":"\u28ff"},{"timestamp":961,"value":"\u28ff"},{"timestamp":161,"value":"\u28b6"},{"timestamp":1673,"value":"\u2809"},{"timestamp":1562,"value":"\u2800"},{"timestamp":112,"value":"\u2800"},{"timestamp":835,"value":"\u2800"},{"timestamp":208,"value":"\u2800"},{"timestamp":203,"value":"\u288e"},{"timestamp":1307,"value":"\u2800"},{"timestamp":503,"value":"\u28ff"},{"timestamp":1522,"value":"\u28bf"},{"timestamp":1070,"value":"\u28d2"},{"timestamp":1506,"value":"\u28e7"},{"timestamp":1576,"value":"\u287b"},{"timestamp":970,"value":"\u2800"},{"timestamp":1593,"value":"\u2800"},{"timestamp":1342,"value":"\u2800"},{"timestamp":177,"value":"\u2800"},{"timestamp":730,"value":"\u2800"},{"timestamp":431,"value":"\u2800"},{"timestamp":1664,"value":"\u2812"},{"timestamp":1709,"value":"p"},{"timestamp":753,"value":"\u28e7"},{"timestamp":50,"value":"\u2800"},{"timestamp":293,"value":"\u2800"},{"timestamp":1117,"value":"\u2800"},{"timestamp":1401,"value":"\u28c0"},{"timestamp":463,"value":"\u28e4"},{"timestamp":188,"value":"\u2800"},{"timestamp":10,"value":"\u2800"},{"timestamp":154,"value":"\u2800"},{"timestamp":524,"value":"\u2880"},{"timestamp":1128,"value":"\u28ff"},{"timestamp":495,"value":"\u28df"},{"timestamp":1302,"value":"\u2800"},{"timestamp":86,"value":"\u28e0"},{"timestamp":1507,"value":"\u28c4"},{"timestamp":1614,"value":"\u28c0"},{"timestamp":897,"value":"\u28c0"},{"timestamp":1315,"value":"\u2803"},{"timestamp":456,"value":"\u2800"},{"timestamp":142,"value":"\u2804"},{"timestamp":1094,"value":"\u2800"},{"timestamp":575,"value":"\u2800"},{"timestamp":1629,"value":"\u2800"},{"timestamp":891,"value":"\u2808"},{"timestamp":403,"value":"\u28d9"},{"timestamp":9,"value":"\u2800"},{"timestamp":168,"value":"\u2800"},{"timestamp":1085,"value":"\u28ff"},{"timestamp":1512,"value":"\u2800"},{"timestamp":1447,"value":"\u2800"},{"timestamp":1099,"value":"\n"},{"timestamp":797,"value":"\u28ff"},{"timestamp":1013,"value":"\u2864"},{"timestamp":1508,"value":"\u28c0"},{"timestamp":559,"value":"\u28ff"},{"timestamp":382,"value":"\u28ff"},{"timestamp":1402,"value":"\u2840"},{"timestamp":1239,"value":"\u2800"},{"timestamp":892,"value":"\u2847"},{"timestamp":1624,"value":"\u2800"},{"timestamp":1205,"value":"\u28ff"},{"timestamp":215,"value":"\u2809"},{"timestamp":1042,"value":"\u28ff"},{"timestamp":1144,"value":"\u28ff"},{"timestamp":1207,"value":"\u28ff"},{"timestamp":516,"value":"\u2800"},{"timestamp":502,"value":"\u28ff"},{"timestamp":734,"value":"\u2800"},{"timestamp":1715,"value":"i"},{"timestamp":1193,"value":"\u28b6"},{"timestamp":1160,"value":"\n"},{"timestamp":1292,"value":"\u2800"},{"timestamp":1404,"value":"\n"},{"timestamp":544,"value":"\u2800"},{"timestamp":877,"value":"\u2800"},{"timestamp":664,"value":"\u2800"},{"timestamp":1422,"value":"\u28c0"},{"timestamp":1142,"value":"\u2800"},{"timestamp":1317,"value":"\u28bb"},{"timestamp":1082,"value":"\u28ff"},{"timestamp":5,"value":"\u2800"},{"timestamp":438,"value":"\u28ff"},{"timestamp":1368,"value":"\u28e6"},{"timestamp":602,"value":"\u2800"},{"timestamp":1316,"value":"\u287c"},{"timestamp":1248,"value":"\u285f"},{"timestamp":1120,"value":"\u2800"},{"timestamp":1329,"value":"\u28c3"},{"timestamp":617,"value":"\u28ff"},{"timestamp":838,"value":"\u28ff"},{"timestamp":1728,"value":"f"},{"timestamp":643,"value":"\u287e"},{"timestamp":266,"value":"\u28ff"},{"timestamp":20,"value":"\u2800"},{"timestamp":444,"value":"\u28ff"},{"timestamp":422,"value":"\u2800"},{"timestamp":1171,"value":"\u2800"},{"timestamp":337,"value":"\u280a"},{"timestamp":943,"value":"\u28b8"},{"timestamp":375,"value":"\u28fe"},{"timestamp":1021,"value":"\u28ff"},{"timestamp":1103,"value":"\u28ff"},{"timestamp":1286,"value":"\u2800"},{"timestamp":1138,"value":"\u2800"},{"timestamp":764,"value":"\u2841"},{"timestamp":241,"value":"\u2800"},{"timestamp":1280,"value":"\u2800"},{"timestamp":1580,"value":"\u2812"},{"timestamp":1224,"value":"\u2808"},{"timestamp":1294,"value":"\u281b"},{"timestamp":1415,"value":"\u2800"},{"timestamp":440,"value":"\u28ff"},{"timestamp":388,"value":"\u28ff"},{"timestamp":1603,"value":"\u2800"},{"timestamp":264,"value":"\u28ff"},{"timestamp":35,"value":"\u2824"},{"timestamp":553,"value":"\u2800"},{"timestamp":547,"value":"\u2800"},{"timestamp":620,"value":"\u28ff"},{"timestamp":758,"value":"\u28c7"},{"timestamp":960,"value":"\u28ff"},{"timestamp":630,"value":"\u28bf"},{"timestamp":353,"value":"\u2800"},{"timestamp":1154,"value":"\u2800"},{"timestamp":847,"value":"\u2800"},{"timestamp":103,"value":"\u2800"},{"timestamp":256,"value":"\u28c0"},{"timestamp":1184,"value":"\u2816"},{"timestamp":369,"value":"\u2800"},{"timestamp":1101,"value":"\u283b"},{"timestamp":1526,"value":"\n"},{"timestamp":1684,"value":"\u2812"},{"timestamp":43,"value":"\u2800"},{"timestamp":1467,"value":"\u2800"},{"timestamp":362,"value":"\u2800"},{"timestamp":64,"value":"\u2800"},{"timestamp":1572,"value":"\u2812"},{"timestamp":487,"value":"\u2800"},{"timestamp":1613,"value":"\u28c0"},{"timestamp":861,"value":"\u28ff"},{"timestamp":584,"value":"\u28ff"},{"timestamp":1077,"value":"\u281f"},{"timestamp":866,"value":"\u2800"},{"timestamp":1247,"value":"\u2800"},{"timestamp":67,"value":"\u2800"},{"timestamp":563,"value":"\u28ff"},{"timestamp":1229,"value":"\u2881"},{"timestamp":1148,"value":"\u28ff"},{"timestamp":1311,"value":"\u28c0"},{"timestamp":590,"value":"\u28ff"},{"timestamp":829,"value":"\u28d2"},{"timestamp":1324,"value":"\u2800"},{"timestamp":156,"value":"\u28c0"},{"timestamp":1485,"value":"\u2800"},{"timestamp":725,"value":"\u2800"},{"timestamp":874,"value":"\u2844"},{"timestamp":210,"value":"\u2800"},{"timestamp":1346,"value":"\u2800"},{"timestamp":1531,"value":"\u2800"},{"timestamp":1719,"value":"r"},{"timestamp":485,"value":"\u2800"},{"timestamp":30,"value":"\u2836"},{"timestamp":1273,"value":"\u2800"},{"timestamp":1692,"value":"\u2800"},{"timestamp":222,"value":"\u2844"},{"timestamp":1698,"value":"\u2800"},{"timestamp":19,"value":"\u2800"},{"timestamp":876,"value":"\u2800"},{"timestamp":800,"value":"\u28ff"},{"timestamp":429,"value":"\u2800"},{"timestamp":1652,"value":"\u2800"},{"timestamp":1256,"value":"\u28fc"},{"timestamp":962,"value":"\u28ff"},{"timestamp":982,"value":"\u28ff"},{"timestamp":920,"value":"\u28ff"},{"timestamp":399,"value":"\u2800"},{"timestamp":29,"value":"\u2874"},{"timestamp":969,"value":"\u2800"},{"timestamp":405,"value":"\u28ff"},{"timestamp":746,"value":"\u2800"},{"timestamp":1182,"value":"\u2824"},{"timestamp":319,"value":"\u28f4"},{"timestamp":656,"value":"\u28ff"},{"timestamp":686,"value":"\u281f"},{"timestamp":732,"value":"\u2800"},{"timestamp":685,"value":"\u287f"},{"timestamp":1075,"value":"\u2800"},{"timestamp":1016,"value":"\u2880"},{"timestamp":106,"value":"\u2800"},{"timestamp":27,"value":"\u2880"},{"timestamp":671,"value":"\u2800"},{"timestamp":599,"value":"\u28f6"},{"timestamp":484,"value":"\u2800"},{"timestamp":1190,"value":"\u2800"},{"timestamp":466,"value":"\u28ff"},{"timestamp":311,"value":"\u2800"},{"timestamp":174,"value":"\u2800"},{"timestamp":1584,"value":"\u28ae"},{"timestamp":61,"value":"\u2800"},{"timestamp":1490,"value":"\u2800"},{"timestamp":735,"value":"\u2800"},{"timestamp":1123,"value":"\u2819"},{"timestamp":1384,"value":"\u2847"},{"timestamp":65,"value":"\u2800"},{"timestamp":124,"value":"\u2800"},{"timestamp":529,"value":"\u28ff"},{"timestamp":1523,"value":"\u28ed"},{"timestamp":457,"value":"\u2800"},{"timestamp":1335,"value":"\u28e4"},{"timestamp":742,"value":"\u28ff"},{"timestamp":914,"value":"\u2800"},{"timestamp":1178,"value":"\u28c0"},{"timestamp":755,"value":"\u2800"},{"timestamp":1552,"value":"\u2800"},{"timestamp":21,"value":"\u2800"},{"timestamp":443,"value":"\u28ff"},{"timestamp":731,"value":"\u2800"},{"timestamp":1216,"value":"\u2800"},{"timestamp":997,"value":"\u2833"},{"timestamp":898,"value":"\u28ff"},{"timestamp":676,"value":"\u28ff"},{"timestamp":670,"value":"\u2800"},{"timestamp":474,"value":"\u28dd"},{"timestamp":1002,"value":"\u2800"},{"timestamp":729,"value":"\u2800"},{"timestamp":778,"value":"\u28ff"},{"timestamp":45,"value":"\u2800"},{"timestamp":1243,"value":"\u2800"},{"timestamp":1279,"value":"\u2800"},{"timestamp":1681,"value":"\u283f"},{"timestamp":822,"value":"\u283f"},{"timestamp":132,"value":"\u2800"},{"timestamp":939,"value":"\u2800"},{"timestamp":660,"value":"\u28ff"},{"timestamp":70,"value":"\u2800"},{"timestamp":677,"value":"\u28ff"},{"timestamp":190,"value":"\u2800"},{"timestamp":4,"value":"\u2800"},{"timestamp":1041,"value":"\u28ff"},{"timestamp":351,"value":"\u2840"},{"timestamp":317,"value":"\u28fe"},{"timestamp":1597,"value":"\u2800"},{"timestamp":856,"value":"\u28a0"},{"timestamp":558,"value":"\u28ff"},{"timestamp":632,"value":"\u2801"},{"timestamp":1408,"value":"\u2800"},{"timestamp":1560,"value":"\u2840"},{"timestamp":904,"value":"\u28ef"},{"timestamp":593,"value":"\u28ff"},{"timestamp":1153,"value":"\u2800"},{"timestamp":1355,"value":"\u2800"},{"timestamp":624,"value":"\u28ff"},{"timestamp":25,"value":"\u2800"},{"timestamp":1472,"value":"\u2800"},{"timestamp":949,"value":"\u2847"},{"timestamp":79,"value":"\u2800"},{"timestamp":1388,"value":"\u2807"},{"timestamp":1500,"value":"\u28ff"},{"timestamp":1537,"value":"\u2880"},{"timestamp":988,"value":"\u28c7"},{"timestamp":1394,"value":"\u2874"},{"timestamp":367,"value":"\n"},{"timestamp":1411,"value":"\u2808"},{"timestamp":1102,"value":"\u28ff"},{"timestamp":954,"value":"\u2800"},{"timestamp":583,"value":"\u28ff"},{"timestamp":1428,"value":"\u2836"},{"timestamp":173,"value":"\u2800"},{"timestamp":570,"value":"\u28ff"},{"timestamp":76,"value":"\u2800"}] -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from faker import Faker 2 | import json 3 | from kafka import KafkaProducer 4 | import time 5 | import sys 6 | import random 7 | import argparse 8 | from pizzaproducer import PizzaProvider 9 | from userbehaviorproducer import UserBehaviorProvider 10 | from stockproducer import StockProvider 11 | from realstockproducer import RealStockProvider 12 | from metricproducer import MetricProvider 13 | from userbets import UserBetsProvider 14 | from rolling import RollingProvider 15 | from metricadvancedproducer import MetricAdvancedProvider 16 | 17 | 18 | MAX_NUMBER_PIZZAS_IN_ORDER = 10 19 | MAX_ADDITIONAL_TOPPINGS_IN_PIZZA = 5 20 | 21 | 22 | # Creating a Faker instance and seeding to have the 23 | # same results every time we execute the script 24 | fake = Faker() 25 | Faker.seed(4321) 26 | 27 | 28 | # function produce_msgs starts producing messages with Faker 29 | def produce_msgs( 30 | security_protocol="SSL", 31 | sasl_mechanism="SCRAM-SHA-256", 32 | cert_folder="~/kafka-pizza/", 33 | username="", 34 | password="", 35 | hostname="hostname", 36 | port="1234", 37 | topic_name="pizza-orders", 38 | nr_messages=-1, 39 | max_waiting_time_in_sec=5, 40 | subject="pizza", 41 | ): 42 | if security_protocol.upper() == "PLAINTEXT": 43 | producer = KafkaProducer( 44 | bootstrap_servers=hostname + ":" + port, 45 | security_protocol="PLAINTEXT", 46 | value_serializer=lambda v: json.dumps(v).encode("ascii"), 47 | key_serializer=lambda v: json.dumps(v).encode("ascii"), 48 | ) 49 | elif security_protocol.upper() == "SSL": 50 | producer = KafkaProducer( 51 | bootstrap_servers=hostname + ":" + port, 52 | security_protocol="SSL", 53 | ssl_cafile=cert_folder + "/ca.pem", 54 | ssl_certfile=cert_folder + "/service.cert", 55 | ssl_keyfile=cert_folder + "/service.key", 56 | value_serializer=lambda v: json.dumps(v).encode("ascii"), 57 | key_serializer=lambda v: json.dumps(v).encode("ascii"), 58 | ) 59 | elif security_protocol.upper() == "SASL_SSL": 60 | producer = KafkaProducer( 61 | bootstrap_servers=hostname + ":" + port, 62 | security_protocol="SASL_SSL", 63 | sasl_mechanism=sasl_mechanism, 64 | ssl_cafile=cert_folder + "/ca.pem" if cert_folder else None, 65 | sasl_plain_username=username, 66 | sasl_plain_password=password, 67 | value_serializer=lambda v: json.dumps(v).encode("ascii"), 68 | key_serializer=lambda v: json.dumps(v).encode("ascii"), 69 | ) 70 | else: 71 | sys.exit("This security protocol is not supported!") 72 | 73 | if nr_messages <= 0: 74 | nr_messages = float("inf") 75 | i = 0 76 | 77 | if subject == "stock": 78 | fake.add_provider(StockProvider) 79 | elif subject == "realstock": 80 | fake.add_provider(RealStockProvider) 81 | elif subject == "metric": 82 | fake.add_provider(MetricProvider) 83 | elif subject == "advancedmetric": 84 | fake.add_provider(MetricAdvancedProvider) 85 | elif subject == "userbehaviour": 86 | fake.add_provider(UserBehaviorProvider) 87 | elif subject == "bet": 88 | fake.add_provider(UserBetsProvider) 89 | elif subject == "rolling": 90 | fake.add_provider(RollingProvider) 91 | else: 92 | fake.add_provider(PizzaProvider) 93 | while i < nr_messages: 94 | if subject in [ 95 | "stock", 96 | "userbehaviour", 97 | "realstock", 98 | "metric", 99 | "bet", 100 | "rolling", 101 | "advancedmetric", 102 | ]: 103 | message, key = fake.produce_msg() 104 | else: 105 | message, key = fake.produce_msg( 106 | fake, 107 | i, 108 | MAX_NUMBER_PIZZAS_IN_ORDER, 109 | MAX_ADDITIONAL_TOPPINGS_IN_PIZZA, 110 | ) 111 | 112 | print("Sending: {}".format(message)) 113 | # sending the message to Kafka 114 | producer.send(topic_name, key=key, value=message) 115 | # Sleeping time 116 | sleep_time = ( 117 | random.randint(0, int(max_waiting_time_in_sec * 10000)) / 10000 118 | ) 119 | print("Sleeping for..." + str(sleep_time) + "s") 120 | time.sleep(sleep_time) 121 | 122 | # Force flushing of all messages 123 | if (i % 100) == 0: 124 | producer.flush() 125 | i = i + 1 126 | producer.flush() 127 | 128 | 129 | # calling the main produce_msgs function: parameters are: 130 | # * nr_messages: number of messages to produce 131 | # * max_waiting_time_in_sec: maximum waiting time in sec between messages 132 | 133 | 134 | def main(): 135 | parser = argparse.ArgumentParser() 136 | parser.add_argument( 137 | "--security-protocol", 138 | help="""Security protocol for Kafka 139 | (PLAINTEXT, SSL, SASL_SSL)""", 140 | required=True, 141 | ) 142 | parser.add_argument( 143 | "--sasl-mechanism", 144 | help="""SASL mechanism for Kafka 145 | (PLAIN, GSSAPI, OAUTHBEARER, SCRAM-SHA-256, SCRAM-SHA-512)""", 146 | required=False, 147 | ) 148 | parser.add_argument( 149 | "--cert-folder", 150 | help="""Path to folder containing required Kafka certificates. 151 | Required --security-protocol equal SSL or SASL_SSL""", 152 | required=False, 153 | ) 154 | parser.add_argument( 155 | "--username", 156 | help="Username. Required if security-protocol is SASL_SSL", 157 | required=False, 158 | ) 159 | parser.add_argument( 160 | "--password", 161 | help="Password. Required if security-protocol is SASL_SSL", 162 | required=False, 163 | ) 164 | parser.add_argument( 165 | "--host", 166 | help="Kafka Host (obtained from Aiven console)", 167 | required=True, 168 | ) 169 | parser.add_argument( 170 | "--port", 171 | help="Kafka Port (obtained from Aiven console)", 172 | required=True, 173 | ) 174 | parser.add_argument("--topic-name", help="Topic Name", required=True) 175 | parser.add_argument( 176 | "--nr-messages", 177 | help="Number of messages to produce (0 for unlimited)", 178 | required=True, 179 | ) 180 | parser.add_argument( 181 | "--max-waiting-time", 182 | help="Max waiting time between messages (0 for none)", 183 | required=True, 184 | ) 185 | parser.add_argument( 186 | "--subject", 187 | help="""What type of content to produce (possible choices areL 188 | [pizza, userbehaviour, stock, 189 | realstock, metric, advancedmetric] 190 | pizza is the default""", 191 | required=False, 192 | ) 193 | args = parser.parse_args() 194 | p_security_protocol = args.security_protocol 195 | p_cert_folder = args.cert_folder 196 | p_username = args.username 197 | p_password = args.password 198 | p_sasl_mechanism = args.sasl_mechanism 199 | p_hostname = args.host 200 | p_port = args.port 201 | p_topic_name = args.topic_name 202 | p_subject = args.subject 203 | produce_msgs( 204 | security_protocol=p_security_protocol, 205 | cert_folder=p_cert_folder, 206 | username=p_username, 207 | password=p_password, 208 | hostname=p_hostname, 209 | port=p_port, 210 | topic_name=p_topic_name, 211 | nr_messages=int(args.nr_messages), 212 | max_waiting_time_in_sec=float(args.max_waiting_time), 213 | subject=p_subject, 214 | sasl_mechanism=p_sasl_mechanism, 215 | ) 216 | print(args.nr_messages) 217 | 218 | 219 | if __name__ == "__main__": 220 | main() 221 | -------------------------------------------------------------------------------- /metricadvancedproducer.py: -------------------------------------------------------------------------------- 1 | from faker.providers import BaseProvider 2 | import random 3 | import time 4 | 5 | NUMBER_HOSTS = 100000 6 | NUMBER_CPU = 30 7 | 8 | 9 | class MetricAdvancedProvider(BaseProvider): 10 | def hostname(self): 11 | return "hostname" + str(random.randint(0, NUMBER_HOSTS)) 12 | 13 | def cpu_id(self): 14 | 15 | return "cpu" + str(random.randint(0, NUMBER_CPU)) 16 | 17 | def usage(self): 18 | return random.random() * 30 + 70 19 | 20 | def produce_msg(self): 21 | hostname = self.hostname() 22 | ts = time.time() 23 | message = { 24 | "hostname": hostname, 25 | "cpu": self.cpu_id(), 26 | "usage": self.usage(), 27 | "occurred_at": int(ts * 1000), 28 | } 29 | key = {"hostname": hostname} 30 | return message, key 31 | -------------------------------------------------------------------------------- /metricproducer.py: -------------------------------------------------------------------------------- 1 | from faker.providers import BaseProvider 2 | import random 3 | import time 4 | 5 | 6 | class MetricProvider(BaseProvider): 7 | def hostname(self): 8 | validIds = [ 9 | "doc", 10 | "grumpy", 11 | "sleepy", 12 | "bashful", 13 | "happy", 14 | "sneezy", 15 | "dopey", 16 | ] 17 | return validIds[random.randint(0, len(validIds) - 1)] 18 | 19 | def cpu_id(self): 20 | validIds = ["cpu1", "cpu2", "cpu3", "cpu4", "cpu5"] 21 | return validIds[random.randint(0, len(validIds) - 1)] 22 | 23 | def usage(self): 24 | return random.random() * 30 + 70 25 | 26 | def produce_msg(self): 27 | hostname = self.hostname() 28 | ts = time.time() 29 | message = { 30 | "hostname": hostname, 31 | "cpu": self.cpu_id(), 32 | "usage": self.usage(), 33 | "occurred_at": int(ts * 1000), 34 | } 35 | key = {"hostname": hostname} 36 | return message, key 37 | -------------------------------------------------------------------------------- /pizzaproducer.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | from faker.providers import BaseProvider 4 | 5 | # Adding a PizzaProvider with 3 methods: 6 | # * pizza_name to retrieve the name of the basic pizza, 7 | # * pizza_topping for additional toppings 8 | # * pizza_shop to retrieve one of the shops available 9 | 10 | 11 | class PizzaProvider(BaseProvider): 12 | def pizza_name(self): 13 | valid_pizza_names = [ 14 | "Margherita", 15 | "Marinara", 16 | "Diavola", 17 | "Mari & Monti", 18 | "Salami", 19 | "Peperoni", 20 | ] 21 | return random.choice(valid_pizza_names) 22 | 23 | def pizza_topping(self): 24 | available_pizza_toppings = [ 25 | "🍅 tomato", 26 | "🧀 blue cheese", 27 | "🥚 egg", 28 | "🫑 green peppers", 29 | "🌶️ hot pepper", 30 | "🥓 bacon", 31 | "🫒 olives", 32 | "🧄 garlic", 33 | "🐟 tuna", 34 | "🧅 onion", 35 | "🍍 pineapple", 36 | "🍓 strawberry", 37 | "🍌 banana", 38 | ] 39 | return random.choice(available_pizza_toppings) 40 | 41 | def pizza_shop(self): 42 | pizza_shops = [ 43 | "Marios Pizza", 44 | "Luigis Pizza", 45 | "Circular Pi Pizzeria", 46 | "Ill Make You a Pizza You Can" "t Refuse", 47 | "Mammamia Pizza", 48 | "Its-a me! Mario Pizza!", 49 | ] 50 | return random.choice(pizza_shops) 51 | 52 | def produce_msg( 53 | self, 54 | FakerInstance, 55 | ordercount=1, 56 | max_pizzas_in_order=5, 57 | max_toppings_in_pizza=3, 58 | ): 59 | shop = FakerInstance.pizza_shop() 60 | # Each Order can have 1-10 pizzas in it 61 | pizzas = [] 62 | for pizza in range(random.randint(1, max_pizzas_in_order)): 63 | # Each Pizza can have 0-5 additional toppings on it 64 | toppings = [] 65 | for topping in range(random.randint(0, max_toppings_in_pizza)): 66 | toppings.append(FakerInstance.pizza_topping()) 67 | pizzas.append( 68 | { 69 | "pizzaName": FakerInstance.pizza_name(), 70 | "additionalToppings": toppings, 71 | } 72 | ) 73 | # message composition 74 | message = { 75 | "id": ordercount, 76 | "shop": shop, 77 | "name": FakerInstance.unique.name(), 78 | "phoneNumber": FakerInstance.unique.phone_number(), 79 | "address": FakerInstance.address(), 80 | "pizzas": pizzas, 81 | "timestamp": int(time.time() * 1000), 82 | } 83 | key = {"shop": shop} 84 | return message, key 85 | -------------------------------------------------------------------------------- /realstockproducer.py: -------------------------------------------------------------------------------- 1 | from faker.providers import BaseProvider 2 | import random 3 | import time 4 | from yahoo_fin import stock_info as si 5 | 6 | StockNames = ["BTC-USD", "ETH-USD", "BNB-USD", "ADA-USD", "DOGE-USD"] 7 | 8 | 9 | class RealStockProvider(BaseProvider): 10 | def stock_name(self): 11 | return random.choice(StockNames) 12 | 13 | def stock_value(self, stockname): 14 | nextval = si.get_live_price(stockname) 15 | return nextval 16 | 17 | def produce_msg(self): 18 | stockname = self.stock_name() 19 | ts = time.time() 20 | message = { 21 | "stock_name": stockname, 22 | "stock_value": self.stock_value(stockname), 23 | "timestamp": int(ts * 1000), 24 | } 25 | key = {"stock_name": stockname} 26 | return message, key 27 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | yahoo_fin 2 | faker 3 | kafka-python -------------------------------------------------------------------------------- /rolling.py: -------------------------------------------------------------------------------- 1 | import time 2 | from faker.providers import BaseProvider 3 | import json 4 | import os 5 | import sys 6 | 7 | 8 | nr_item = 0 9 | base_timestamp = int(time.time() * 1000) 10 | f = open(os.path.join(sys.path[0], "data_rolling.json")) 11 | data = json.load(f) 12 | 13 | # Adding a RollingProvider with 1 method: 14 | # * getcode to retrieve the username 15 | 16 | 17 | class RollingProvider(BaseProvider): 18 | def produce_msg(self): 19 | 20 | global nr_item 21 | global base_timestamp 22 | item = data[nr_item] 23 | 24 | # message composition 25 | message = { 26 | "val": item["value"], 27 | "ts": base_timestamp + int(item["timestamp"]), 28 | } 29 | key = {"ts": base_timestamp + int(item["timestamp"])} 30 | if nr_item == 1732: 31 | print("Waiting next iteration") 32 | time.sleep(30) 33 | nr_item = 0 34 | base_timestamp = int(time.time() * 1000) 35 | else: 36 | nr_item = nr_item + 1 37 | return message, key 38 | -------------------------------------------------------------------------------- /stockproducer.py: -------------------------------------------------------------------------------- 1 | from faker.providers import BaseProvider 2 | import random 3 | import time 4 | 5 | 6 | StockNames = [ 7 | "Deja Brew", 8 | "Jurassic Pork", 9 | "Lawn & Order", 10 | "Pita Pan", 11 | "Bread Pitt", 12 | "Indiana Jeans", 13 | "Thai Tanic", 14 | ] 15 | StockCurrentValues = [10.0, 20.1, 20.2, 12.1, 25.1, 25.1, 27.5] 16 | StockUpProb = [0.5, 0.6, 0.7, 0.8, 0.9, 0.4, 0.3] 17 | ShuffleProb = 0.2 18 | ChangeAmount = 0.8 19 | 20 | 21 | class StockProvider(BaseProvider): 22 | def stock_name(self): 23 | return random.choice(StockNames) 24 | 25 | def stock_value(self, stockname): 26 | indexStock = StockNames.index(stockname) 27 | currentval = StockCurrentValues[indexStock] 28 | goesup = 1 29 | if random.random() > StockUpProb[indexStock]: 30 | goesup = -1 31 | nextval = currentval + random.random() * ChangeAmount * goesup 32 | StockCurrentValues[indexStock] = nextval 33 | 34 | return nextval 35 | 36 | def reshuffle_probs(self, stockname): 37 | indexStock = StockNames.index(stockname) 38 | StockUpProb[indexStock] = random.random() 39 | 40 | def produce_msg(self): 41 | stockname = self.stock_name() 42 | ts = time.time() 43 | if random.random() > ShuffleProb: 44 | self.reshuffle_probs(stockname) 45 | message = { 46 | "stock_name": stockname, 47 | "stock_value": self.stock_value(stockname), 48 | "timestamp": int(ts * 1000), 49 | } 50 | key = {"user": "all_users"} 51 | return message, key 52 | -------------------------------------------------------------------------------- /userbehaviorproducer.py: -------------------------------------------------------------------------------- 1 | from faker.providers import BaseProvider 2 | import random 3 | import time 4 | import datetime 5 | 6 | 7 | class UserBehaviorProvider(BaseProvider): 8 | def user_id(self): 9 | userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9] 10 | return random.choice(userIds) 11 | 12 | def item_id(self): 13 | validIds = [21, 22, 23, 24, 25, 26, 27, 28, 29] 14 | return random.choice(validIds) 15 | 16 | def behavior(self): 17 | behaviorNames = ["view", "cart", "buy"] 18 | return random.choice(behaviorNames) 19 | 20 | def group_name(self): 21 | groupNames = ["A", "B"] 22 | return random.choice(groupNames) 23 | 24 | def view_id(self): 25 | viewIds = [111, 222, 555] 26 | return random.choice(viewIds) 27 | 28 | def produce_msg(self): 29 | ts = time.time() - random.randint(-5, 5) 30 | b = self.behavior() 31 | view_id = None 32 | if b == "view": 33 | view_id = self.view_id() 34 | message = { 35 | "user_id": self.user_id(), 36 | "item_id": self.item_id(), 37 | "behavior": b, 38 | "view_id": view_id, 39 | "group_name": self.group_name(), 40 | "occurred_at": datetime.datetime.fromtimestamp(ts).strftime( 41 | "%Y-%m-%d %H:%M:%S" 42 | ), 43 | } 44 | key = {"user": "all_users"} 45 | return message, key 46 | -------------------------------------------------------------------------------- /userbets.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | from faker.providers import BaseProvider 4 | 5 | MIN_AMOUNT = 2 # Min betting amount 6 | MAX_AMOUNT = 1000 # Max betting amount 7 | 8 | ALPHA = 50 9 | 10 | # Adding a UserBets with 3 methods: 11 | # * username to retrieve the username, 12 | # * bet_amount to retrieve the amount 13 | # * betting_channel_event to retrieve event and channel 14 | 15 | 16 | class UserBetsProvider(BaseProvider): 17 | def username(self): 18 | valid_usernames = [ 19 | "nopineappleonpizza", 20 | "catanzaro99", 21 | "thedoctor", 22 | "bettingexpert01", 23 | "losingmoney66", 24 | "manutd007", 25 | "manutd009", 26 | "citylife1", 27 | "lysa_X", 28 | "aiventest", 29 | ] 30 | return random.choice(valid_usernames) 31 | 32 | def bet_amount(self): 33 | # return int(random.triangular(MIN_AMOUNT, MID_AMOUNT, MAX_AMOUNT)) 34 | return ( 35 | int((random.paretovariate(ALPHA) - 1) * (MAX_AMOUNT - MIN_AMOUNT)) 36 | + 1 37 | ) 38 | 39 | def bet_category_event(self): 40 | valid_events = [ 41 | { 42 | "category": "Sport", 43 | "subcategory": "Football", 44 | "event": "ManUTD vs Chelsea", 45 | }, 46 | { 47 | "category": "Sport", 48 | "subcategory": "Box", 49 | "event": "Chicken Legs vs Power Kick", 50 | }, 51 | { 52 | "category": "Sport", 53 | "subcategory": "Curling", 54 | "event": "Italy vs England", 55 | }, 56 | { 57 | "category": "Sport", 58 | "subcategory": "Netball", 59 | "event": "Sydney vs Camberra", 60 | }, 61 | { 62 | "category": "Lottery", 63 | "subcategory": "Bingo", 64 | "event": "Uk Bingo", 65 | }, 66 | { 67 | "category": "Lottery", 68 | "subcategory": "WinForLife", 69 | "event": "Win For Life America", 70 | }, 71 | { 72 | "category": "Event", 73 | "subcategory": "Music", 74 | "event": "Rick Astley #1 in World Charts", 75 | }, 76 | { 77 | "category": "Event", 78 | "subcategory": "Politics", 79 | "event": "Mickey Mouse new Italian President", 80 | }, 81 | { 82 | "category": "Event", 83 | "subcategory": "Celebrities", 84 | "event": "Donald Duck and Marge Simpson Wedding", 85 | }, 86 | ] 87 | return random.choice(valid_events) 88 | 89 | def produce_msg(self): 90 | username = self.username() 91 | bet_amount = self.bet_amount() 92 | bet_event = self.bet_category_event() 93 | 94 | # message composition 95 | message = { 96 | "username": username, 97 | "event": { 98 | "category": bet_event["category"], 99 | "subcategory": bet_event["subcategory"], 100 | "name": bet_event["event"], 101 | }, 102 | "amount": bet_amount, 103 | "timestap": int(time.time() * 1000), 104 | } 105 | key = {"event": bet_event["event"]} 106 | return message, key 107 | --------------------------------------------------------------------------------