buelon 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. buelon-1.0.0/MANIFEST.in +5 -0
  2. buelon-1.0.0/PKG-INFO +309 -0
  3. buelon-1.0.0/README.md +284 -0
  4. buelon-1.0.0/buelon/__init__.py +10 -0
  5. buelon-1.0.0/buelon/bucket.py +386 -0
  6. buelon-1.0.0/buelon/command_line.py +328 -0
  7. buelon-1.0.0/buelon/core/__init__.py +19 -0
  8. buelon-1.0.0/buelon/core/action.py +67 -0
  9. buelon-1.0.0/buelon/core/execution.py +314 -0
  10. buelon-1.0.0/buelon/core/loop.py +135 -0
  11. buelon-1.0.0/buelon/core/pipe.py +117 -0
  12. buelon-1.0.0/buelon/core/pipe_debug.py +89 -0
  13. buelon-1.0.0/buelon/core/pipe_interpreter.py +189 -0
  14. buelon-1.0.0/buelon/core/step.py +189 -0
  15. buelon-1.0.0/buelon/core/step_definition.py +142 -0
  16. buelon-1.0.0/buelon/cython/__init__.py +10 -0
  17. buelon-1.0.0/buelon/cython/c_bucket.c +19624 -0
  18. buelon-1.0.0/buelon/cython/c_bucket.pyx +380 -0
  19. buelon-1.0.0/buelon/cython/c_hub.c +30669 -0
  20. buelon-1.0.0/buelon/cython/c_hub.pyx +699 -0
  21. buelon-1.0.0/buelon/cython/c_worker.c +18582 -0
  22. buelon-1.0.0/buelon/cython/c_worker.pyx +260 -0
  23. buelon-1.0.0/buelon/examples/__init__.py +8 -0
  24. buelon-1.0.0/buelon/examples/demo.py +77 -0
  25. buelon-1.0.0/buelon/examples/example.pipe +86 -0
  26. buelon-1.0.0/buelon/examples/example.py +198 -0
  27. buelon-1.0.0/buelon/helpers/__init__.py +12 -0
  28. buelon-1.0.0/buelon/helpers/json_parser.py +84 -0
  29. buelon-1.0.0/buelon/helpers/pipe_util.py +218 -0
  30. buelon-1.0.0/buelon/helpers/postgres.py +426 -0
  31. buelon-1.0.0/buelon/helpers/sqlite3_helper.py +194 -0
  32. buelon-1.0.0/buelon/hub.py +705 -0
  33. buelon-1.0.0/buelon/worker.py +265 -0
  34. buelon-1.0.0/buelon.egg-info/PKG-INFO +309 -0
  35. buelon-1.0.0/buelon.egg-info/SOURCES.txt +40 -0
  36. buelon-1.0.0/buelon.egg-info/dependency_links.txt +1 -0
  37. buelon-1.0.0/buelon.egg-info/entry_points.txt +2 -0
  38. buelon-1.0.0/buelon.egg-info/requires.txt +6 -0
  39. buelon-1.0.0/buelon.egg-info/top_level.txt +1 -0
  40. buelon-1.0.0/pyproject.toml +2 -0
  41. buelon-1.0.0/setup.cfg +4 -0
  42. buelon-1.0.0/setup.py +61 -0
@@ -0,0 +1,5 @@
1
+ include buelon/cython/*.pyx
2
+ include buelon/examples/example.pipe
3
+ include README.md
4
+ include LICENSE
5
+ include .env
buelon-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,309 @@
1
+ Metadata-Version: 2.1
2
+ Name: buelon
3
+ Version: 1.0.0
4
+ Summary: A system and language to handle any process using multiple workers for some(planned for most) languages
5
+ Home-page: https://github.com/daniel-olson-code/buelon
6
+ Author: Daniel Olson
7
+ Author-email: daniel@orphos.cloud
8
+ Keywords: buelon etl pipeline asynchronous data-processing api
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: Cython
20
+ Requires-Dist: psycopg2-binary
21
+ Requires-Dist: orjson
22
+ Requires-Dist: python-dotenv
23
+ Requires-Dist: asyncio-pool
24
+ Requires-Dist: psutil
25
+
26
+ # Pipeline
27
+
28
+ Pipeline is an asynchronous ETL (Extract, Transform, Load) system that uses a custom scripting language to run code across multiple servers, one step at a time. It's designed for efficient handling of large-scale data processing tasks, particularly those involving APIs with long wait times or I/O-heavy workloads.
29
+
30
+ ## Table of Contents
31
+ - [Features](#features)
32
+ - [Installation](#installation)
33
+ - [Quick Start](#quick-start)
34
+ - [Supported Languages](#supported-languages)
35
+ - [Configuration](#configuration)
36
+ - [Usage](#usage)
37
+ - [Learn by Example](#learn-by-example)
38
+ - [Performance](#performance) <!--- - [Contributing](#contributing) -->
39
+ - [Future of Pipeline](#plans)
40
+ - [License](#license)
41
+
42
+ ## Features
43
+ - Asynchronous execution of code across multiple servers
44
+ - Custom scripting language for defining ETL pipelines
45
+ - Support for Python, SQLite3, and PostgreSQL
46
+ - Efficient handling of APIs with long wait times
47
+ - Optimized for I/O-heavy workloads
48
+ - Scalable architecture for processing large amounts of data
49
+
50
+ ## Installation
51
+ 1. Clone the repository: `git clone https://github.com/yourusername/pipeline.git
52
+ cd pipeline`
53
+ 2. Install required packages: `pip install -r requirements.txt`
54
+ 3. (Optional) Build Cython files: `python build.py` (This can give a 3x performance boost)
55
+ 4. (Optional) Configure PostgreSQL settings in the `.env` file.
56
+
57
+ ## Quick Start
58
+ 1. Run the demo server: `python demo.py`
59
+ 2. In a separate terminal, run the example uploading code: `python example.py`
60
+
61
+ ## Supported Languages
62
+ - Python
63
+ - SQLite3
64
+ - PostgreSQL
65
+
66
+ ## Configuration
67
+ * Setup at least 4 servers on a private network (they can be small, you can technically run all these on one server like `demo.py` does but that's not recommended)
68
+ * Create a server running `python bucket.py` or something like `python -c "import c_bucket;c_bucket.main()"`
69
+ * Create a server running `python pipeline.py` or something like `python -c "import c_pipeline;c_pipeline.main()"`
70
+ * Create a server running `python worker.py` or something like `python -c "import c_worker;c_worker.main()"`
71
+ * Edit the `.env` on each server to access the private ip. Change `PIPE_WORKER_HOST` to refer to the server running `pipeline.py` on server running `worker.py` and change `BUCKET_CLIENT_HOST` to refer to the server running `bucket.py` on both the `worker.py` server and the `pipeline.py` server
72
+ * Add "worker" servers until desired speed
73
+ * Create a server with private and public network access and use this to run `pipeline.upload_pipe_code_from_file` or `pipeline.upload_pipe_code` uploading the script to the server to be run.
74
+ * All workers must also have the files necessary to run your code, pip installs and all
75
+
76
+
77
+ * (Optionally) The `PIPE_WORKER_SUBPROCESS_JOBS` value within the `.env` file can be set to `true` or `false`(really anything but true). This configuration lets you run python code in a subprocess or within the "worker" script. Setting it to false gives a very slight performance increase, but requires you restart the server every time you make a change to your project.
78
+
79
+
80
+ ## Usage
81
+
82
+ Pipeline uses a custom scripting language to define ETL processes. Here's how to use it:
83
+
84
+ ### Basic Structure
85
+
86
+ A Pipeline script consists of steps and pipes. Each step defines a task, and pipes determine the order of execution.
87
+
88
+ ```python
89
+ # Step definition
90
+ step_name:
91
+ language
92
+ function_or_table_name
93
+ source_file_or_code
94
+
95
+ # Pipe definition
96
+ pipe_name = step1 | step2 | step3
97
+
98
+ # Execution
99
+ pipe_name()
100
+ ```
101
+
102
+ ### Supported Languages
103
+
104
+ - python: For Python code
105
+ - sqlite3: For SQLite queries
106
+ - postgres: For PostgreSQL queries
107
+
108
+ ### Scopes and Priorities
109
+
110
+ Use scopes and priorities to control execution:
111
+
112
+ ```python
113
+ $ production # Set default scope
114
+
115
+
116
+ step_name:
117
+ python
118
+ !9 # Set priority (higher numbers run first within their scope)
119
+ $ testing # Set a lower priority scope
120
+ function_name
121
+ source_file
122
+ ```
123
+
124
+ ### Writing Code Directly
125
+
126
+ For short snippets, you can write code directly in the script:
127
+
128
+ ```python
129
+ step_name:
130
+ sqlite3
131
+ table_name
132
+ `
133
+ SELECT * FROM table_name
134
+ WHERE condition = 'value'
135
+ `
136
+ ```
137
+
138
+ ### Defining Pipes
139
+
140
+ Pipes determine the order of step execution:
141
+
142
+ ```python
143
+ single_pipe = | step1 # or `step1 |`
144
+ normal_pipe = step1 | step2 | step3
145
+ ```
146
+
147
+ ### Executing Pipes
148
+
149
+ There are two ways to execute pipes:
150
+
151
+ #### Single call
152
+
153
+ ```python
154
+ pipe1()
155
+ result1 = pipe2()
156
+ result2 = pipe3(result1)
157
+ pipe4(result2)
158
+
159
+ pipe5(result1, result2)
160
+
161
+ # incorrect --> `pipe3(pipe2())` # this syntax is currently not supported
162
+ # also incorrect, they must be on one line as of now:
163
+ # `pipe3(
164
+ # result1
165
+ # )`
166
+ ```
167
+
168
+ #### Looped execution
169
+
170
+ ```python
171
+ for item in pipe1():
172
+ pipe2(item)
173
+ # incorrect --> `for item in pipe1(result):` # syntax not supported for now
174
+ ```
175
+
176
+ ### Running Your Pipeline
177
+
178
+ - Save your pipeline script as a .pipe file.
179
+ - Use the Pipeline API to upload and run your script:
180
+ ```python
181
+ # example.py
182
+ import pipeline
183
+
184
+ pipeline.upload_pipe_code_from_file('your_script.pipe')
185
+ ```
186
+
187
+
188
+ ## Learn by Example
189
+
190
+ ```python
191
+ # the default scope is set to `production-small` for all steps (imports)
192
+ # setting scopes is how you make new steps with errors
193
+ # not slow down your servers by setting them to a lower scope.
194
+ # And/or how you handle processes that either require and do not require big machines to run
195
+ $ production-small
196
+
197
+ # step 1: `accounts`
198
+ accounts:
199
+ python # <-- select the language to be run. currently only python, sqlite3 and postgres are available
200
+ accounts # define the function or table name that will be used
201
+ example.py # either provide a file or write code directly using the "`" char (see below example)
202
+
203
+ request:
204
+ python
205
+ request_report
206
+ example.py
207
+
208
+ status:
209
+ python
210
+ $ testing-small # <-- "scope" for a single step. A lower scope will be given less priority over higher scopes. See PIPE_WORKER_SCOPES in `.env` file
211
+ get_status
212
+ example.py
213
+
214
+ download:
215
+ python
216
+ !9 # <-- "priority" higher numbers are more important and run first within their scope.
217
+ get_report
218
+ example.py
219
+
220
+ manipulate_data:
221
+ sqlite3
222
+ some_table # *vvvv* see below for writing code directly *vvvv*
223
+ `
224
+ SELECT
225
+ *,
226
+ CASE
227
+ WHEN sales = 0
228
+ THEN 0.0
229
+ ELSE spend / sales
230
+ END AS acos
231
+ FROM some_table
232
+ `
233
+
234
+ ## this one's just to show postgres as well
235
+ #manipulate_data_again:
236
+ # postgres
237
+ # another_table
238
+ # `
239
+ #select
240
+ # *,
241
+ # case
242
+ # when spend = 0
243
+ # then 0.0
244
+ # else sales / spend
245
+ # end AS roas
246
+ #from another_table
247
+ #`
248
+
249
+ upload:
250
+ python
251
+ upload_to_db
252
+ example.py
253
+
254
+
255
+ # these are pipes and what will tell the server what order to run the steps
256
+ # and also transfer the returned data between steps
257
+ # each step will be run individually and could be run on a different computer each time
258
+ accounts_pipe = | accounts # single pipes currently need a `|` before or behind the value
259
+ api_pipe = request | status | download | manipulate_data | upload
260
+
261
+
262
+ # currently there are only two syntax's for "running" pipes.
263
+ # either by itself:
264
+ # pipe()
265
+ #
266
+ # or in a loop:
267
+ # for value in pipe1():
268
+ # pipe2(value)
269
+
270
+ # # Another Example:
271
+ # v = pipe(accounts_pipe) # <-- single call
272
+ # pipe2(v)
273
+
274
+ # right not you cannot pass arguments within the pipe being used for the for loop.
275
+ # in this case `accounts_pipe()` cannot be `accounts_pipe(some_value)`
276
+ for account in accounts_pipe():
277
+ api_pipe(account)
278
+ ```
279
+
280
+ ## Performance
281
+ Pipeline is specifically designed to handle I/O-heavy workloads efficiently. It excels in scenarios such as:
282
+
283
+ - Making numerous API calls, especially to services with long processing times
284
+ - Handling large-scale data transfers between different systems
285
+ - Concurrent database operations
286
+
287
+ For instance, Pipeline is currently being used by an agency to request 30,000 reports daily from the Amazon Ads API, resulting in at least 90,000 API calls per day. This process, which includes pushing data into a PostgreSQL server with over 600 GB of data, is completed within a few hours(adding more workers could make this alot faster). The system's efficiency allows for this level of performance at a cost of under $100, including database expenses, actually the servers requesting the data are about $25.
288
+
289
+ The asynchronous nature of Pipeline makes it particularly suited for APIs like Amazon Ads, where there are significant wait times between requesting a report and its availability for download. Traditional synchronous ETL processes struggle with such APIs, especially for agencies with numerous profiles.
290
+
291
+ ## Plans
292
+
293
+ If this projects sees some love, or I just find more free time, I'd like to support more languages. Even compiled languages such as `rust`, `go` and `c++`. Allowing teams that write different languages to work on the same program.
294
+
295
+ Turning this project into a pip package.
296
+
297
+ I want to rewrite this in rust for performance.
298
+
299
+
300
+ <!---
301
+ your comment goes here
302
+ and here
303
+
304
+ ## Contributing
305
+ [Contributing guidelines]
306
+ -->
307
+
308
+ ## License
309
+ * MIT License
buelon-1.0.0/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # Pipeline
2
+
3
+ Pipeline is an asynchronous ETL (Extract, Transform, Load) system that uses a custom scripting language to run code across multiple servers, one step at a time. It's designed for efficient handling of large-scale data processing tasks, particularly those involving APIs with long wait times or I/O-heavy workloads.
4
+
5
+ ## Table of Contents
6
+ - [Features](#features)
7
+ - [Installation](#installation)
8
+ - [Quick Start](#quick-start)
9
+ - [Supported Languages](#supported-languages)
10
+ - [Configuration](#configuration)
11
+ - [Usage](#usage)
12
+ - [Learn by Example](#learn-by-example)
13
+ - [Performance](#performance) <!--- - [Contributing](#contributing) -->
14
+ - [Future of Pipeline](#plans)
15
+ - [License](#license)
16
+
17
+ ## Features
18
+ - Asynchronous execution of code across multiple servers
19
+ - Custom scripting language for defining ETL pipelines
20
+ - Support for Python, SQLite3, and PostgreSQL
21
+ - Efficient handling of APIs with long wait times
22
+ - Optimized for I/O-heavy workloads
23
+ - Scalable architecture for processing large amounts of data
24
+
25
+ ## Installation
26
+ 1. Clone the repository: `git clone https://github.com/yourusername/pipeline.git
27
+ cd pipeline`
28
+ 2. Install required packages: `pip install -r requirements.txt`
29
+ 3. (Optional) Build Cython files: `python build.py` (This can give a 3x performance boost)
30
+ 4. (Optional) Configure PostgreSQL settings in the `.env` file.
31
+
32
+ ## Quick Start
33
+ 1. Run the demo server: `python demo.py`
34
+ 2. In a separate terminal, run the example uploading code: `python example.py`
35
+
36
+ ## Supported Languages
37
+ - Python
38
+ - SQLite3
39
+ - PostgreSQL
40
+
41
+ ## Configuration
42
+ * Setup at least 4 servers on a private network (they can be small, you can technically run all these on one server like `demo.py` does but that's not recommended)
43
+ * Create a server running `python bucket.py` or something like `python -c "import c_bucket;c_bucket.main()"`
44
+ * Create a server running `python pipeline.py` or something like `python -c "import c_pipeline;c_pipeline.main()"`
45
+ * Create a server running `python worker.py` or something like `python -c "import c_worker;c_worker.main()"`
46
+ * Edit the `.env` on each server to access the private ip. Change `PIPE_WORKER_HOST` to refer to the server running `pipeline.py` on server running `worker.py` and change `BUCKET_CLIENT_HOST` to refer to the server running `bucket.py` on both the `worker.py` server and the `pipeline.py` server
47
+ * Add "worker" servers until desired speed
48
+ * Create a server with private and public network access and use this to run `pipeline.upload_pipe_code_from_file` or `pipeline.upload_pipe_code` uploading the script to the server to be run.
49
+ * All workers must also have the files necessary to run your code, pip installs and all
50
+
51
+
52
+ * (Optionally) The `PIPE_WORKER_SUBPROCESS_JOBS` value within the `.env` file can be set to `true` or `false`(really anything but true). This configuration lets you run python code in a subprocess or within the "worker" script. Setting it to false gives a very slight performance increase, but requires you restart the server every time you make a change to your project.
53
+
54
+
55
+ ## Usage
56
+
57
+ Pipeline uses a custom scripting language to define ETL processes. Here's how to use it:
58
+
59
+ ### Basic Structure
60
+
61
+ A Pipeline script consists of steps and pipes. Each step defines a task, and pipes determine the order of execution.
62
+
63
+ ```python
64
+ # Step definition
65
+ step_name:
66
+ language
67
+ function_or_table_name
68
+ source_file_or_code
69
+
70
+ # Pipe definition
71
+ pipe_name = step1 | step2 | step3
72
+
73
+ # Execution
74
+ pipe_name()
75
+ ```
76
+
77
+ ### Supported Languages
78
+
79
+ - python: For Python code
80
+ - sqlite3: For SQLite queries
81
+ - postgres: For PostgreSQL queries
82
+
83
+ ### Scopes and Priorities
84
+
85
+ Use scopes and priorities to control execution:
86
+
87
+ ```python
88
+ $ production # Set default scope
89
+
90
+
91
+ step_name:
92
+ python
93
+ !9 # Set priority (higher numbers run first within their scope)
94
+ $ testing # Set a lower priority scope
95
+ function_name
96
+ source_file
97
+ ```
98
+
99
+ ### Writing Code Directly
100
+
101
+ For short snippets, you can write code directly in the script:
102
+
103
+ ```python
104
+ step_name:
105
+ sqlite3
106
+ table_name
107
+ `
108
+ SELECT * FROM table_name
109
+ WHERE condition = 'value'
110
+ `
111
+ ```
112
+
113
+ ### Defining Pipes
114
+
115
+ Pipes determine the order of step execution:
116
+
117
+ ```python
118
+ single_pipe = | step1 # or `step1 |`
119
+ normal_pipe = step1 | step2 | step3
120
+ ```
121
+
122
+ ### Executing Pipes
123
+
124
+ There are two ways to execute pipes:
125
+
126
+ #### Single call
127
+
128
+ ```python
129
+ pipe1()
130
+ result1 = pipe2()
131
+ result2 = pipe3(result1)
132
+ pipe4(result2)
133
+
134
+ pipe5(result1, result2)
135
+
136
+ # incorrect --> `pipe3(pipe2())` # this syntax is currently not supported
137
+ # also incorrect, they must be on one line as of now:
138
+ # `pipe3(
139
+ # result1
140
+ # )`
141
+ ```
142
+
143
+ #### Looped execution
144
+
145
+ ```python
146
+ for item in pipe1():
147
+ pipe2(item)
148
+ # incorrect --> `for item in pipe1(result):` # syntax not supported for now
149
+ ```
150
+
151
+ ### Running Your Pipeline
152
+
153
+ - Save your pipeline script as a .pipe file.
154
+ - Use the Pipeline API to upload and run your script:
155
+ ```python
156
+ # example.py
157
+ import pipeline
158
+
159
+ pipeline.upload_pipe_code_from_file('your_script.pipe')
160
+ ```
161
+
162
+
163
+ ## Learn by Example
164
+
165
+ ```python
166
+ # the default scope is set to `production-small` for all steps (imports)
167
+ # setting scopes is how you make new steps with errors
168
+ # not slow down your servers by setting them to a lower scope.
169
+ # And/or how you handle processes that either require and do not require big machines to run
170
+ $ production-small
171
+
172
+ # step 1: `accounts`
173
+ accounts:
174
+ python # <-- select the language to be run. currently only python, sqlite3 and postgres are available
175
+ accounts # define the function or table name that will be used
176
+ example.py # either provide a file or write code directly using the "`" char (see below example)
177
+
178
+ request:
179
+ python
180
+ request_report
181
+ example.py
182
+
183
+ status:
184
+ python
185
+ $ testing-small # <-- "scope" for a single step. A lower scope will be given less priority over higher scopes. See PIPE_WORKER_SCOPES in `.env` file
186
+ get_status
187
+ example.py
188
+
189
+ download:
190
+ python
191
+ !9 # <-- "priority" higher numbers are more important and run first within their scope.
192
+ get_report
193
+ example.py
194
+
195
+ manipulate_data:
196
+ sqlite3
197
+ some_table # *vvvv* see below for writing code directly *vvvv*
198
+ `
199
+ SELECT
200
+ *,
201
+ CASE
202
+ WHEN sales = 0
203
+ THEN 0.0
204
+ ELSE spend / sales
205
+ END AS acos
206
+ FROM some_table
207
+ `
208
+
209
+ ## this one's just to show postgres as well
210
+ #manipulate_data_again:
211
+ # postgres
212
+ # another_table
213
+ # `
214
+ #select
215
+ # *,
216
+ # case
217
+ # when spend = 0
218
+ # then 0.0
219
+ # else sales / spend
220
+ # end AS roas
221
+ #from another_table
222
+ #`
223
+
224
+ upload:
225
+ python
226
+ upload_to_db
227
+ example.py
228
+
229
+
230
+ # these are pipes and what will tell the server what order to run the steps
231
+ # and also transfer the returned data between steps
232
+ # each step will be run individually and could be run on a different computer each time
233
+ accounts_pipe = | accounts # single pipes currently need a `|` before or behind the value
234
+ api_pipe = request | status | download | manipulate_data | upload
235
+
236
+
237
+ # currently there are only two syntax's for "running" pipes.
238
+ # either by itself:
239
+ # pipe()
240
+ #
241
+ # or in a loop:
242
+ # for value in pipe1():
243
+ # pipe2(value)
244
+
245
+ # # Another Example:
246
+ # v = pipe(accounts_pipe) # <-- single call
247
+ # pipe2(v)
248
+
249
+ # right not you cannot pass arguments within the pipe being used for the for loop.
250
+ # in this case `accounts_pipe()` cannot be `accounts_pipe(some_value)`
251
+ for account in accounts_pipe():
252
+ api_pipe(account)
253
+ ```
254
+
255
+ ## Performance
256
+ Pipeline is specifically designed to handle I/O-heavy workloads efficiently. It excels in scenarios such as:
257
+
258
+ - Making numerous API calls, especially to services with long processing times
259
+ - Handling large-scale data transfers between different systems
260
+ - Concurrent database operations
261
+
262
+ For instance, Pipeline is currently being used by an agency to request 30,000 reports daily from the Amazon Ads API, resulting in at least 90,000 API calls per day. This process, which includes pushing data into a PostgreSQL server with over 600 GB of data, is completed within a few hours(adding more workers could make this alot faster). The system's efficiency allows for this level of performance at a cost of under $100, including database expenses, actually the servers requesting the data are about $25.
263
+
264
+ The asynchronous nature of Pipeline makes it particularly suited for APIs like Amazon Ads, where there are significant wait times between requesting a report and its availability for download. Traditional synchronous ETL processes struggle with such APIs, especially for agencies with numerous profiles.
265
+
266
+ ## Plans
267
+
268
+ If this projects sees some love, or I just find more free time, I'd like to support more languages. Even compiled languages such as `rust`, `go` and `c++`. Allowing teams that write different languages to work on the same program.
269
+
270
+ Turning this project into a pip package.
271
+
272
+ I want to rewrite this in rust for performance.
273
+
274
+
275
+ <!---
276
+ your comment goes here
277
+ and here
278
+
279
+ ## Contributing
280
+ [Contributing guidelines]
281
+ -->
282
+
283
+ ## License
284
+ * MIT License
@@ -0,0 +1,10 @@
1
+ # Import modules from subpackages
2
+ from . import bucket, hub, worker, command_line
3
+ from .core import action, execution, loop, pipe, pipe_interpreter, step, step_definition
4
+ from .cython import c_bucket, c_hub, c_worker
5
+ from .helpers import json_parser, pipe_util, postgres, sqlite3_helper
6
+ from .examples import demo, example
7
+
8
+
9
+ # Define the public API
10
+ __all__ = ['bucket', 'hub', 'worker', 'command_line', 'core', 'cython', 'helpers', 'cython', 'examples']