def audio_encoder(sources): # Parse configuration parser = create_arg_parser() read_request, read_response = sources.argv.argv.pipe( ops.skip(1), argparse.parse(parser), ops.filter(lambda i: i.key == 'config'), ops.map(lambda i: file.Read(id='config', path=i.value)), file.read(sources.file.response), ) config = read_response.pipe( ops.filter(lambda i: i.id == "config"), ops.flat_map(lambda i: i.data), parse_config, ) # Transcode request handling encode_init = config.pipe( ops.map( lambda i: encoder.Initialize(storage_path=i.encode.storage_path))) encode_request = sources.httpd.route.pipe( ops.filter(lambda i: i.id == 'flac_transcode'), ops.flat_map(lambda i: i.request), ops.map(lambda i: encoder.EncodeMp3( id=i.context, data=i.data, key=i.match_info['key'])), ) encoder_request = rx.merge(encode_init, encode_request) # http server http_init = config.pipe( ops.flat_map(lambda i: rx.from_([ httpd.Initialize(request_max_size=0), httpd.AddRoute( methods=['POST'], path='/api/transcode/v1/flac/{key:[a-zA-Z0-9-\._]*}', id='flac_transcode', ), httpd.StartServer(host=i.server.http.host, port=i.server.http.port ), ]))) http_response = sources.encoder.response.pipe( ops.map(lambda i: httpd.Response( data='ok'.encode('utf-8'), context=i.id, ))) http = rx.merge(http_init, http_response) # merge sink requests file_requests = read_request return Sink( encoder=encoder.Sink(request=encoder_request), file=file.Sink(request=file_requests), httpd=httpd.Sink(control=http), )
def model_publisher(scheduler, sources): file_source = sources.file.response.pipe(ops.share()) # kafka driver bootstrap. fixme kafka_source = sources.kafka.response.pipe( ops.do_action(print), ops.replay(), ops.ref_count(), ) kafka_source.subscribe() config, config_read_request, http_request = read_config_from_args( sources.argv.argv, file_source, sources.http.response, scheduler=scheduler) config = config.pipe(ops.first()) kafka_request = config.pipe(ops.map(lambda c: create_model_topics(c)), ) return ModelPublisherSink( file=file.Sink(request=rx.merge(config_read_request)), http=http.Sink(request=http_request), kafka=kafka.Sink(request=kafka_request), )
def main(): # setup gui image = Image.open(IMAGE_FILE) image_width, image_height = image.size window_size = RectSize(width=image_width, height=image_height) window = initialize_window(window_size) canvas = create_canvas_on(window, window_size, canvas_place=Point(0, 0)) image_tk = ImageTk.PhotoImage(image) canvas.create_image(0, 0, image=image_tk, anchor="nw") def draw_rect(rectangle): canvas.delete("rect") draw_rect_on( canvas, rectangle, fill_color="orange", stipple="gray12", outline_color="orange", width=1.0, tag="rect", ) # state mouse_left_click = createMouseEventStream(window, "<Button-1>") mouse_left_drag = createMouseEventStream(window, "<B1-Motion>") rect_begin = mouse_left_click rect_end = rx.merge(mouse_left_drag, mouse_left_click) rect = rx.combine_latest(rect_begin, rect_end).pipe( ops.map(lambda tpl: rect_from_2points(*tpl))) rect.subscribe(draw_rect) window.mainloop()
def rmux_client(sources): response = sources.tcp_client.response.pipe(ops.share()) tcp_connect = rx.just(tcp_client.Connect( host='127.0.0.1', port='8080' )) create_observable = response.pipe( ops.flat_map(lambda connection: rx.just({'what': 'subscribe', 'id':42, 'name': '1234'}).pipe( ops.map(lambda i: json.dumps(i)), frame, ops.map(lambda j: tcp_client.Write(id=connection.id, data=j.encode())) )) ) console = response.pipe( ops.flat_map(lambda connection: connection.observable.pipe( ops.map(lambda i: i.data.decode('utf-8')), unframe, ops.map(lambda i: json.loads(i)), ops.group_by(lambda i: i['id']), ops.flat_map(lambda subscription: subscription.pipe( ops.map(notification), ops.dematerialize(), )) )), ops.map(lambda i: "item: {}\n".format(i)) ) tcp_sink = rx.merge(tcp_connect, create_observable) return Sink( tcp_client=tcp_client.Sink(request=tcp_sink), stdout=stdout.Sink(data=console), )
def __init__(self, error_handler: ErrorHandler) -> None: if error_handler is None: raise ValueError("Argument 'error_handler' is required.") super().__init__() self._error_handler = error_handler self._added_window = Subject() self._removed_window = Subject() changed_window = rx.merge( self._added_window.pipe(ops.map(lambda v: (v, True))), self._removed_window.pipe(ops.map(lambda v: (v, False)))) def on_window_change(windows: Tuple[Window, ...], event: Tuple[Window, bool]): (window, added) = event if added and window not in windows: return windows + (window,) elif not added and window in windows: return tuple(c for c in windows if c is not window) # noinspection PyTypeChecker self.windows = changed_window.pipe( ops.scan(on_window_change, ()), ops.start_with(()), ops.distinct_until_changed())
def __init__( self, add=None, remove=None, reindex=None, clear=None, edit_at_index=None, initial_state=None, ): self.add = Subject() if add is None else add self.remove = Subject() if remove is None else remove self.reindex = Subject() if reindex is None else reindex self.clear = Subject() if clear is None else clear self.edit_at_index = Subject( ) if edit_at_index is None else edit_at_index self.initial_state = pr.v() if initial_state is None else initial_state self.history = rx.merge(self.add, self.remove, self.reindex, self.clear, self.edit_at_index) self._values = self.history.pipe( ops.scan(self.reduce_list_state, self.initial_state)) self.values = self._values self.values_with_history = self._values.pipe( ops.zip(self.history), # ops.replay(buffer_size=1) )
def __init__( self, columns, add_row=None, remove_row=None, edit_row_at_index=None, clear=None, initial_rows=None, ): self.add_row = Subject() if add_row is None else add_row self.remove_row = Subject() if remove_row is None else remove_row self.clear = Subject() if clear is None else clear self.edit_row_at_index = Subject( ) if edit_row_at_index is None else edit_row_at_index self.initial_rows = pr.v() if initial_rows is None else initial_rows self.initial_columns = pr.v(*columns) self.history = rx.merge(self.add_row, self.remove_row, self.clear, self.edit_row_at_index) self._values_with_columns = self.history.pipe( ops.scan( self.reduce_table_state, (self.initial_rows, self.initial_columns), )) self.values = self._values_with_columns.pipe(ops.map(lambda x: x[0])) self.columns = self._values_with_columns.pipe(ops.map(lambda x: x[1])) self.values_with_history = self.values.pipe(ops.zip(self.history))
def _watch_lift_health(self, building_map): lifts: Sequence[Lift] = building_map.lifts if building_map else [] def to_lift_health(data: Tuple[str, bool]): id_ = data[0] has_heartbeat = data[1] if has_heartbeat: return ttm.LiftHealth(id_=id_, health_status=ttm.HealthStatus.HEALTHY) return ttm.LiftHealth( id_=id_, health_status=ttm.HealthStatus.DEAD, health_message="heartbeat failed", ) keys = [x.name for x in lifts] initial_values: Sequence[Tuple[str, Any]] = [(k, None) for k in keys] obs = rx.merge( rx.of(*initial_values), self.rmf.lift_states.pipe(ops.map(lambda x: (x.lift_name, x))), ) lift_mode_health = obs.pipe(ops.map(self._lift_mode_to_health)) heartbeat_health = obs.pipe( self._watch_heartbeat(lambda x: x[0]), ops.map(to_lift_health), ) sub = heartbeat_health.pipe( self._combine_most_critical(lift_mode_health)).subscribe( self.rmf.lift_health.on_next, scheduler=self.scheduler) self._building_watchers.append(sub)
def _export_year(geometry, year_start, year_end, export_description, year_dir): stack = _create_stack(geometry, year_start, year_end) initial_progress = of({ 'exported': 0, 'stack_bytes': 0, 'dates_bytes': 0, 'downloaded': 0, 'processed': 0 }) def aggregate_downloaded_bytes(p): return { 'exported': p['exported'], 'downloaded': p['downloaded'], 'downloaded_bytes': p['stack_bytes'] + p['dates_bytes'], 'processed': p['processed'] } return concat( initial_progress, merge( _export_and_download_stack(stack, export_description, year_dir), _export_and_download_dates(stack, export_description, year_dir)), _process_year(year_dir), of({'processed': 1})).pipe(scan(lambda acc, p: { **acc, **p }, {}), map(aggregate_downloaded_bytes))
def demo_merge1(): obs1 = rx.from_([1, 2, 3, 4]) obs2 = rx.from_([5, 6, 7, 8]) res = rx.merge(obs1, obs2) res.subscribe(print)
def events(file_handler, connection_handler, store): return rx.concat( _initialize(), rx.merge( _new_files(file_handler), _connection_statuses(connection_handler), _failed_transfers(store), ))
def on_invalidate(self, component: T) -> Observable: other_changes = super().on_invalidate(component) children_changes = component.observe("children") def child_bounds_changes(child: Component): return rx.merge(child.observe("bounds"), child.observe("preferred_size"), child.observe("minimum_size")) children_bounds_changes = children_changes.pipe( ops.map(lambda children: map(child_bounds_changes, children)), ops.map(lambda b: rx.merge(*b)), ops.switch_latest(), ops.map(lambda _: None)) return rx.merge(other_changes, children_changes, children_bounds_changes, component.layout.on_constraints_change)
def demo_merge2(): obs1 = rx.from_([1, 2, 3, 4]) obs2 = rx.from_([5, 6, 7, 8]) obs_list = [obs1, obs2] res = rx.merge(*obs_list) res.subscribe(print)
def on_mouse_wheel(self) -> Observable: def on_wheel(code: int) -> Observable: return self._activeInputs.pipe( ops.filter(lambda i: code in i), ops.map(lambda i: i[code].values[-1]), ops.filter(lambda v: v != 0)) return rx.merge(on_wheel(bge.events.WHEELUPMOUSE), on_wheel(bge.events.WHEELDOWNMOUSE))
def __init__(self, context: Context): super().__init__(context) def dispatch(event: PositionalEvent) -> None: self.context.dispatcher_at( event.position).map(lambda d: d.dispatch_event(event)) self._dispatchers = rx.merge(*self.positional_events) \ .pipe(ops.take_until(self.on_dispose)) \ .subscribe(dispatch, on_error=self.error_handler)
def on_invalidate(self, component: Canvas) -> Observable: image_changes = component.observe("image") padding_changes = self.on_style_change(component).pipe( ops.filter(lambda e: isinstance(e, InsetsChangeEvent)), ops.filter(lambda e: e.key in component.style_fallback_keys( StyleKeys.Padding))) return rx.merge(super().on_invalidate(component), image_changes, padding_changes)
def on_mouse_up(self) -> Observable: def event_for(button: MouseButton) -> Observable: return self.on_button_release(button).pipe( ops.map(lambda _: rx.concat( rx.of(self.position), rx.never().pipe( ops.take_until(self.on_button_press(button))))), ops.exclusive(), ops.map(lambda p: MouseUpEvent(self.context, p, button))) return rx.merge(*[event_for(button) for button in MouseButton])
def exec(self, func, items): observables: List[rx.Observable] = [] with ProcessPoolExecutor() as executor: for item in items.values(): _future = executor.submit(func, item) observables.append(rx.from_future(_future)) all_observables = rx.merge(*observables) all_observables.subscribe( self._on_success, self._on_error, self._on_complete, )
def _combine_epics( norm_epics: Iterable[Epic], action_: Observable, state_: Observable ) -> Observable: """ Merges the epics into one Args: action_: the action observable state_: the state observable Returns: the merged epic """ return merge(*map(run_epic(action_, state_), norm_epics))
def _initialize_drag(self, ui: FrameUI): offset = rx.merge(self.on_drag_start, self.on_drag).pipe( ops.filter( lambda e: self.draggable and e.button == MouseButton.LEFT), ops.filter(lambda e: ui.allow_drag(self, self.position_of(e))), ops.filter(lambda e: not self.resizable or ui.resize_handle_at( self, e.position) == Nothing), ops.map(lambda e: e.position), ops.pairwise(), ops.map(lambda v: v[1] - v[0]), ops.take_until( self.on_drag_end.pipe( ops.filter(lambda e: e.button == MouseButton.LEFT))), ops.repeat(), ops.take_until(self.on_dispose)) self._drag_listener = offset.subscribe( self.move_by, on_error=self.context.error_handler)
def echo_server(source): init = rx.from_([ httpd.Initialize(), httpd.AddRoute(methods=['GET'], path='/echo/{what}', id='echo'), httpd.StartServer(host='localhost', port=8080), ]) echo = source.httpd.route.pipe( ops.flat_map(lambda i: i.request), ops.map(lambda i: httpd.Response( context=i.context, data=i.match_info['what'].encode('utf-8'))), ) control = rx.merge(init, echo) return EchoSink(httpd=httpd.Sink(control=control))
def operator(source: Observable): completed = Subject() def notifying_source(): return source.pipe(finally_action(lambda: completed.on_next(True))) def aside_source(s): return s.pipe( flat_map(lambda _: empty()), take_until(completed), ) sources_ = tuple([notifying_source()]) + tuple( [aside_source(s) for s in sources]) return merge(*sources_)
def main(sources): ticks_stream = rx.interval(timedelta(seconds=1)).pipe( map(lambda n: n + 1), take(10)) responses_stream = sources["http"].pipe(flat_map(lambda s: s), ) queries = rx.of( { "url": "https://jsonplaceholder.typicode.com/todos/1" }, { "url": "https://error123123123.co.uk" }, ).pipe(delay(timedelta(seconds=2))) return { "log": rx.merge(queries, responses_stream, ticks_stream), "http": queries }
def __init__(self, candle_time, symbol): self.candle_time = candle_time self.symbol = symbol try: sma_5_sub, sma_5_obs = create_stream_ta(candle_time=candle_time) sma_5_obs = sma_5_obs.pipe( ops.map(lambda wlist: TIData( name="SMA", time_interval=5, epoch=wlist[:1, 0][0], data=sma(np.array(wlist[:, 1]).astype(np.float), 5), symbol=self.symbol)), # ops.map(test(4)) ) self.ta_subscribers.append(sma_5_sub) ema_14_sub, ema_14_obs = create_stream_ta(candle_time=candle_time) ema_14_obs = ema_14_obs.pipe( ops.map(lambda wlist: TIData( name="EMA", time_interval=14, epoch=wlist[:1, 0][0], data=sma(np.array(wlist[:, 1]).astype(np.float), 14), symbol=self.symbol)), # ops.map(test(5)) ) self.ta_subscribers.append(ema_14_sub) # rsi_14_sub, rsi_14_obs = create_stream_ta(candle_time=candle_time) rsi_14_obs = rsi_14_obs.pipe( ops.map(lambda wlist: TIData( name="RSI", time_interval=7, epoch=wlist[:1, 0][0], data=rsi(np.array(wlist[:, 1]).astype(np.float), 7), symbol=self.symbol)), # ops.map(test(6)) ) self.ta_subscribers.append(rsi_14_sub) self.ta_result = rx.merge(sma_5_obs, ema_14_obs, rsi_14_obs) except Exception as err: print(err)
def rmux_server(sources): tcp_listen = rx.just(tcp_server.Listen(host='127.0.0.1', port='8080')) beat = sources.tcp_server.response.pipe( ops.flat_map(lambda connection: connection.observable.pipe( ops.map(lambda i: i.data.decode('utf-8')), unframe, ops.map(lambda i: json.loads(i)), ops.flat_map(lambda subscription: create_observable[subscription[ 'name']]().pipe( ops.materialize(), ops.map(lambda i: materialize_repr(i, subscription['id'])), )), ops.map(lambda i: json.dumps(i)), frame, ops.map(lambda j: tcp_server.Write(id=connection.id, data=j.encode()))))) tcp_sink = rx.merge(tcp_listen, beat) return Sink(tcp_server=tcp_server.Sink(request=tcp_sink), )
def on_invalidate(self, component: Label) -> Observable: text_changes = component.observe("text") size_changes = component.observe("text_size") style_changes = self.on_style_change(component) font_changes = style_changes.pipe( ops.filter(lambda e: isinstance(e, FontChangeEvent)), ops.filter(lambda e: e.key in component.style_fallback_keys( StyleKeys.Text))) padding_changes = style_changes.pipe( ops.filter(lambda e: isinstance(e, InsetsChangeEvent)), ops.filter(lambda e: e.key in component.style_fallback_keys( StyleKeys.Padding))) return rx.merge(super().on_invalidate(component), text_changes, size_changes, font_changes, padding_changes)
def __init__(self, context: Context, visible: bool = True) -> None: super().__init__(context, visible) # noinspection PyTypeChecker self.hover = rx.merge( self.on_mouse_over.pipe(ops.map(lambda _: True)), self.on_mouse_out.pipe(ops.map(lambda _: False))).pipe(ops.start_with(False)) mouse = MouseInput.input(self) # noinspection PyTypeChecker self.active = self.on_mouse_down.pipe( ops.filter(lambda e: e.button == MouseButton.LEFT), ops.map(lambda _: rx.concat(rx.of(True), mouse.on_button_release(MouseButton.LEFT).pipe( ops.take(1), ops.map(lambda _: False)))), ops.exclusive(), ops.start_with(False))
def test_route_error(self): actual_sequence = [] def on_chain_item(i): nonlocal actual_sequence actual_sequence.append(i) sink, route_error = make_error_router() origin = rx.from_([rx.just(1), rx.throw(-1)]).pipe( route_error(error_map=lambda e: e.args[0] * 100), ) result = rx.merge(origin, sink) disposable = result.subscribe(on_chain_item, scheduler=CurrentThreadScheduler()) disposable.dispose() expected_sequence = [1, -100] self.assertEqual(actual_sequence, expected_sequence)
def on_drag_leave(self) -> Observable: mouse = MouseInput.input(self) position = mouse.observe("position") from_inside = self.on_mouse_down.pipe( ops.map(lambda e: position.pipe( ops.filter(lambda p: not self.bounds.contains(p - self.offset) ), ops.take(1), ops.map(lambda p: (p, e.button)), ops.take_until(mouse.on_button_release(e.button)))), ops.exclusive()) from_outside = self.on_drag_over.pipe( ops.map(lambda e: self.on_mouse_out.pipe( ops.take(1), ops.map(lambda o: (o.position, e.button)), ops.take_until(mouse.on_button_release(e.button)))), ops.exclusive()) return rx.merge(from_inside, from_outside).pipe( ops.map(lambda e: DragLeaveEvent(self, e[0], e[1])))
def _export_year(geometry, year_start, year_end, export_description, year_dir): stack = _create_stack(geometry, year_start, year_end) ee.InitializeThread(credentials) if not stack.bandNames().size().getInfo(): logging.info('No data between {} and {}'.format( year_start, year_end)) return of({ 'exported': 1, 'downloaded': 1, 'downloaded_bytes': 0, 'processed': 1 }) initial_progress = of({ 'exported': 0, 'stack_bytes': 0, 'dates_bytes': 0, 'downloaded': 0, 'processed': 0 }) def aggregate_downloaded_bytes(p): return { 'exported': p['exported'], 'downloaded': p['downloaded'], 'downloaded_bytes': p['stack_bytes'] + p['dates_bytes'], 'processed': p['processed'] } return concat( initial_progress, merge( _export_and_download_stack(stack, export_description, year_dir), _export_and_download_dates(stack, export_description, year_dir)), _process_year(year_dir), of({'processed': 1})).pipe(scan(lambda acc, p: { **acc, **p }, {}), map(aggregate_downloaded_bytes))
def create(): return rx.merge(e1, r1)
def create(): return rx.merge(r1, e1)
def create(): return rx.merge(o1, o2)
def create(): return rx.merge(n1, n2, n3)
def create(): return rx.merge(e1, e2, e3)
def merge(source: Observable) -> Observable: """Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences. Or merges two observable sequences into a single observable sequence. Examples: >>> res = merge(sources) Args: source: Source observable. Returns: The observable sequence that merges the elements of the inner sequences. """ if max_concurrent is None: sources_ = tuple([source]) + sources return rx.merge(*sources_) def subscribe(observer, scheduler=None): active_count = [0] group = CompositeDisposable() is_stopped = [False] queue = [] def subscribe(xs): subscription = SingleAssignmentDisposable() group.add(subscription) @synchronized(source.lock) def on_completed(): group.remove(subscription) if queue: s = queue.pop(0) subscribe(s) else: active_count[0] -= 1 if is_stopped[0] and active_count[0] == 0: observer.on_completed() on_next = synchronized(source.lock)(observer.on_next) on_error = synchronized(source.lock)(observer.on_error) subscription.disposable = xs.subscribe_(on_next, on_error, on_completed, scheduler) def on_next(inner_source): if active_count[0] < max_concurrent: active_count[0] += 1 subscribe(inner_source) else: queue.append(inner_source) def on_completed(): is_stopped[0] = True if active_count[0] == 0: observer.on_completed() group.add(source.subscribe_(on_next, observer.on_error, on_completed, scheduler)) return group return Observable(subscribe)
import rx from rx import concurrency as ccy from rx import operators as ops source0 = rx.cold('a-----d---1--------4-|', timespan=0.1) source1 = rx.cold('--b-c-------2---3-| ', timespan=0.1) print("to_marbles() is a blocking operator, we need to wait for completion...") print('expecting "a-b-c-d---1-2---3--4-|"') observable = rx.merge(source0, source1).pipe(ops.to_marbles(timespan=0.1)) diagram = observable.run() print('got "{}"'.format(diagram))
import rx import rx.operators as ops """ Use a dictionnary to convert elements declared in the marbles diagram to the specified values. """ lookup0 = {'a': 1, 'b': 3, 'c': 5} lookup1 = {'x': 2, 'y': 4, 'z': 6} source0 = rx.cold('a---b----c----|', timespan=0.01, lookup=lookup0) source1 = rx.cold('---x---y---z--|', timespan=0.01, lookup=lookup1) observable = rx.merge(source0, source1).pipe(ops.to_iterable()) elements = observable.run() print('received {}'.format(list(elements)))
import rx from rx import operators as ops """ Specify the error to be raised in place of the # symbol. """ err = ValueError("I don't like 5!") src0 = rx.from_marbles('12-----4-----67--|', timespan=0.2) src1 = rx.from_marbles('----3----5-# ', timespan=0.2, error=err) source = rx.merge(src0, src1).pipe(ops.do_action(print)) source.run()