Package: turbine-py
TurbineTurbine is a data application framework for building server-side applications that are event-driven, respond to data in real-time, and scale using cloud-native best practices.The benefits of using Turbine include:Native Developer Tooling:Turbine doesn't come with any bespoke DSL or patterns. Write software like you normally would!Fits into Existing DevOps Workflows:Build, test, and deploy. Turbine encourages best practices from the start. Don't test your data app in production ever again.Local Development mirrors Production:When running locally, you'll immediately see how your app reacts to data. What you get there will be exactly what happens in production but withscaleandspeed.Available in many different programming langauages:Turbine started out in Go but is available in other languages too:GoJavascriptPythonGetting StartedTo get started, you'll need to install theturbine-pydependency viapip:pip3installturbine-pyNext, you'll need todownload the Meroxa CLI. Once downloaded and installed, initialize a new project using the following CLI command:$meroxaappsinittestapp--langpyThe CLI will create a new folder calledtestapplocated in the directory where the command was issued. If you want to initialize the app somewhere else, you can append the--pathflag to the command (meroxa apps init testapp --lang py --path ~/anotherdir). Once you enter thetestappdirectory, the contents will look like this:$treetestapp/
testapp
├──README.md
├──main.py
├──app.json
├──__init__.py
└──fixtures├──demo-cdc.json└──demo-no-cdc.jsonThis will be a full-fledged Turbine app that can run. You can even run the tests using the commandmeroxa apps runin the root of the app directory. It provides just enough to show you what you need to get started.main.pyThis configuration file is where you begin your Turbine journey. Any time a Turbine app runs, this is the entry point for the entire application. When the project is created, the file will look like this:# Dependencies of the example data appimporthashlibimportsysfromturbine.src.turbine_appimportRecordList,TurbineAppdefanonymize(records:RecordList)->RecordList:forrecordinrecords:try:payload=record.value["payload"]# Hash the emailpayload["customer_email"]=hashlib.sha256(payload["customer_email"].encode("utf-8")).hexdigest()exceptExceptionase:print("Error occurred while parsing records: "+str(e))returnrecordsclassApp:@staticmethodasyncdefrun(turbine:TurbineApp):try:source=awaitturbine.resources("source_name")records=awaitsource.records("collection_name")anonymized=awaitturbine.process(records,anonymize)destination_db=awaitturbine.resources("destination_name")awaitdestination_db.write(anonymized,"collection_archive")exceptExceptionase:print(e,file=sys.stderr)Let's talk about the important parts of this code. Turbine apps have five functions that comprise the entire DSL. Outside of these functions, you can write whatever code you want to accomplish your tasks:asyncdefrun(turbine:TurbineApp):runis the main entry point for the application. This is where you can initialize the Turbine framework. This is also the place where, when you deploy your Turbine app to Meroxa, Meroxa will use this as the place to boot up the application.source=awaitturbine.resources("source_name")Theresourcesfunction identifies the upstream or downstream system that you want your code to work with. Thesource_nameis the string identifier of the particular system. The string should map to an associated identifier in yourapp.jsonto configure what's being connected to. For more details, see theapp.jsonsection.records=awaitsource.records("collection_name")Once you've gotresourcesset up, you can now stream records from it, but you need to identify what records you want. Therecordsfunction identifies the records or events that you want to stream into your data app.anonymized=awaitturbine.process(records,anonymize)Theprocessfunction is Turbine's way of saying, for the records that are coming in, I want you to process these records against a function. Once your app is deployed on Meroxa, Meroxa will do the work to take each record or event that does get streamed to your app and then run your code against it. This allows Meroxa to scale out your processing relative to the velocity of the records streaming in.awaitdestination_db.write(anonymized,"collection_archive")Thewritefunction is optional. It takes any records given to it and streams them to the downstream system. In many cases, you might not need to stream data to another system, but this gives you an easy way to do so.app.jsonThis file contains all of the options for configuring a Turbine app. Upon initialization of an app, the CLI will scaffold the file for you with available options:{"name":"testapp","language":"python","environment":"common","resources":{"source_name":"fixtures/demo-cdc.json"}}name- The name of your application. This should not change after app initialization.language- Tells Meroxa what language the app is upon deployment.environment- "common" is the only available environment. Meroxa does have the ability to create isolated environments but this feature is currently in beta.resources- These are the named integrations that you'll use in your application. Thesource_nameneeds to match the name of the resource that you'll set up in Meroxa using themeroxa resources createcommand or via the Dashboard. You can point to the path in the fixtures that'll be used to mock the resource when you runmeroxa apps run.FixturesFixtures are JSON-formatted samples of data records you can use while locally developing your Turbine app. Whether CDC or non-CDC-formatted data records, fixtures adhere to the following structure:{"collection_name":[{"key":"1","value":{"schema":{/* ... */},"payload":{/* ... */}}}]}collection_name— Identifies the name of the records or events you are streaming to your data app.key— Denotes one or more sample records within a fixture file.keyis always a string.value— Holds theschemaandpayloadof the sample data record.schema— Comes as part of your sample data record.schemadescribes the record or event structure.payload— Comes as part of your sample data record.payloaddescribes what about the record or event changed.Your newly created data app should have ademo-cdc.jsonanddemo-non-cdc.jsonin the/fixturesdirectory as examples to follow.TestingTesting should follow standard Python development practices.Documentation && ReferenceThe most comprehensive documentation for Turbine and how to work with Turbine apps is on the Meroxa site:https://docs.meroxa.com/ContributingFor information on how to contribute to Turbine-py, checkout our contribution guideHEREExample appsSee what a sample python data app looks like using our framework