Vibhavari Bellutagi
02/27/2023, 2:36 PMDian Fu
02/28/2023, 1:45 AMpython word_count.py
• submit to standalone cluster / yarn cluster / K8s: via flink run , see https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/deployment/cli/#submitting-pyflink-jobs for more details.Vibhavari Bellutagi
02/28/2023, 2:04 PMDian Fu
03/01/2023, 5:33 AMVibhavari Bellutagi
03/01/2023, 10:00 AMVibhavari Bellutagi
03/02/2023, 9:14 PMdef word_count(self, input_data):
text = self.env.from_collection(input_data)
word_count = text.flat_map(lambda x: str(x).lower().split()) \
.map(lambda i: (i, 1), output_type=Types.TUPLE([Types.STRING(), <http://Types.INT|Types.INT>()])) \
.key_by(lambda i: i[0]) \
.reduce(lambda i, j: (i[0], i[1] + j[1]))
word_count.print()
self.env.execute("some-name")
Test that Im trying to run -
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionModefrom services.word_count import WordCountfrom services.test_utils import PyFlinkStreamingTestCase, DataStreamTestSinkFunctionclass WordCountTest(PyFlinkStreamingTestCase):
def setUp(self) -> None:
super(WordCountTest, self).setUp()
self.test_sink = DataStreamTestSinkFunction()
def tearDown(self) -> None:
self.test_sink.clear()
def assert_equals_sorted(self, expected, actual):
expected.sort()
actual.sort()
self.assertEqual(expected, actual)
def test_word_count(self):
env = StreamExecutionEnvironment.get_execution_environment()
env.set_runtime_mode(RuntimeExecutionMode.BATCH)
env.set_parallelism(1)
# Input data input_data = ["ABC is a good boy. ABC works for an XYZ org"]
# Expected output data expected_output = [('abc', 2), ('an', 1), ('for', 1), ('good', 1), ('is', 1), ('org', 1), ('works', 1),
('boy.', 1), ('xyz', 1)]
# Create WordCount object wc = WordCount(env)
# Create collect sink sink = WordCountTest()
# Execute word_count function wc.word_count(input_data).add_sink(sink)
# Get results from collect sink results = self.test_sink.get_results()
# Assert that the actual output matches the expected output self.assert_equals_sorted(results, expected_output)
Can you please help me here.Dian Fu
03/03/2023, 1:40 AMVibhavari Bellutagi
03/03/2023, 9:24 AMVibhavari Bellutagi
03/03/2023, 4:28 PMpip3 install maven and tested via tox but still the error was same.
I also tried the 2nd approach, where the Im keeping test_utils.py and jars in same python package and when I run the tests via tox ( or manually )
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionModefrom services.word_count import WordCountfrom services.test_utils import PyFlinkStreamingTestCase, DataStreamTestSinkFunctionclass WordCountTest(PyFlinkStreamingTestCase):
def setUp(self) -> None:
super(WordCountTest, self).setUp()
self.test_sink = DataStreamTestSinkFunction()
def tearDown(self) -> None:
self.test_sink.clear()
def assert_equals_sorted(self, expected, actual):
expected.sort()
actual.sort()
self.assertEqual(expected, actual)
def test_word_count(self):
env = StreamExecutionEnvironment.get_execution_environment()
env.set_runtime_mode(RuntimeExecutionMode.BATCH)
env.set_parallelism(1)
# Input data input_data = ["ABC is a good boy. ABC works for an XYZ org"]
# Expected output data expected_output = [('abc', 2), ('an', 1), ('for', 1), ('good', 1), ('is', 1), ('org', 1), ('works', 1),
('boy.', 1), ('xyz', 1)]
# Create WordCount object wc = WordCount(env)
# Create collect sink sink = WordCountTest()
# Execute word_count function wc.word_count(input_data).add_sink(sink)
# Get results from collect sink results = self.test_sink.get_results()
# Assert that the actual output matches the expected output self.assert_equals_sorted(results, expected_output)
In above test, Im getting an error in the line ( in the setUp method) -
self.test_sink = DataStreamTestSinkFunction()
TypeError: Could not found the Java class 'org.apache.flink.python.util.DataStreamTestCollectSink'. The Java dependencies could be specified via command line argument '--jarfile' or the config option 'pipeline.jars'
Can you please let me know, if Im missing something or, some other config needs to done.
Thanks a lot for your patience 🙂Dian Fu
03/04/2023, 5:03 AMos.path.pathsep.join(test_jars) https://github.com/dianfu/pyflink-faq/blob/main/testing/test_utils.py#L111 to check if the paths are correct.Vibhavari Bellutagi
03/09/2023, 9:09 AMprint("Construct test classpath")
print(construct_test_classpath())
output:
Construct test classpath
/IdeaProjects/ProjectName/core/tests/servicest/flink-python-1.16.1-tests.jar
Please let me know, what I'm missing in the above code.
Thanks for the patience.Dian Fu
03/09/2023, 9:20 AMTypeError: Could not found the Java class 'org.apache.flink.python.util.DataStreamTestCollectSink'. The Java dependencies could be specified via command line argument '--jarfile' or the config option 'pipeline.jars' ?Vibhavari Bellutagi
03/09/2023, 11:09 AMDian Fu
03/09/2023, 11:12 AMorg.apache.flink.python.util.DataStreamTestCollectSink should exist in flink-python-1.16.1-tests.jar . You could verify it as following:
jar tf /IdeaProjects/ProjectName/core/tests/servicest/flink-python-1.16.1-tests.jar | grep DataStreamTestCollectSinkVibhavari Bellutagi
03/09/2023, 1:08 PMVibhavari Bellutagi
03/09/2023, 1:15 PMDian Fu
03/10/2023, 4:07 AM___init___ , otherwise it will be executed before `PyFlinkStreamingTestCase.___init_`(where we need to do some initialization work, e.g. adding flink-python-1.16.1-tests.jar to classpath, etc) is called.
WordCount(StreamExecutionEnvironment.get_execution_environment()).word_count(
["ABC is a good boy. ABC works for an XYZ org"])Vibhavari Bellutagi
03/10/2023, 10:21 AM___init___" Do you mean to include the code inside the __init__ inside the constructor of test or core class?
class WordCountTest(PyFlinkStreamingTestCase):
def __init__(self):
super().__init__() # this line is giving an error, it is unable to identify the test
WordCount(StreamExecutionEnvironment.get_execution_environment()).word_count(["ABC is a good boy. ABC works for an XYZ org"])
When you say the following line, do you mean with the env?
WordCount(StreamExecutionEnvironment.get_execution_environment()).word_count(
["ABC is a good boy. ABC works for an XYZ org"])Dian Fu
03/11/2023, 1:59 PMfrom pyflink.datastream.stream_execution_environment import StreamExecutionEnvironment, RuntimeExecutionMode
from pyflink.common import Types
class WordCount(object):
def __init__(self, env):
self.env = env
self.env.set_runtime_mode(RuntimeExecutionMode.BATCH)
self.env.set_parallelism(1)
def word_count(self, input_data):
text = self.env.from_collection(input_data)
word_count = text.flat_map(lambda x: str(x).lower().split()) \
.map(lambda i: (i, 1), output_type=Types.TUPLE([Types.STRING(), <http://Types.INT|Types.INT>()])) \
.key_by(lambda i: i[0]) \
.reduce(lambda i, j: (i[0], i[1] + j[1]))
word_count.print()
self.env.execute("some-name")
########################################test case ##############################
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode
from services.word_count import WordCount
from servicest.test_utils import PyFlinkStreamingTestCase, DataStreamTestSinkFunction
class WordCountTest(PyFlinkStreamingTestCase):
def setUp(self) -> None:
super(WordCountTest, self).setUp()
self.test_sink = DataStreamTestSinkFunction()
def tearDown(self) -> None:
self.test_sink.clear()
def assert_equals_sorted(self, expected, actual):
expected.sort()
actual.sort()
self.assertEqual(expected, actual)
def test_word_count(self):
env = StreamExecutionEnvironment.get_execution_environment()
env.set_runtime_mode(RuntimeExecutionMode.BATCH)
env.set_parallelism(1)
# Input data
input_data = ["ABC is a good boy. ABC works for an XYZ org"]
# Expected output data
expected_output = [('abc', 2), ('an', 1), ('for', 1), ('good', 1), ('is', 1), ('org', 1), ('works', 1),
('boy.', 1), ('xyz', 1)]
# Create WordCount object
wc = WordCount(env)
# Create collect sink
sink = WordCountTest()
# Execute word_count function
wc.word_count(input_data).add_sink(sink)
# Get results from collect sink
results = self.test_sink.get_results()
# Assert that the actual output matches the expected output
self.assert_equals_sorted(results, expected_output)
if __name__ == '__main__':
WordCount(StreamExecutionEnvironment.get_execution_environment()).word_count(
["ABC is a good boy. ABC works for an XYZ org"])Dian Fu
03/11/2023, 2:03 PMsetUpClass method of PyFlinkStreamingTestCase should be executed before any PyFlink code to make sure we prepared the testing environment.Vibhavari Bellutagi
03/14/2023, 4:09 PM(a,1)
(an,1)
(is,1)
(abc,2)
(for,1)
(org,1)
(xyz,1)
(boy.,1)
(good,1)
(works,1)
None
But I have this error below -
wc.word_count(input_data).add_sink(sink)
AttributeError: 'NoneType' object has no attribute 'add_sink'
Can you please let me know why we have NoneType?Dian Fu
03/15/2023, 1:42 AMwc.word_count(input_data).add_sink(sink) , it doesn’t return any thing for ``wc.word_count(input_data)``. You should change word_count.print() in the method WordCount.word_count to word_count.add_sink(sink)Vibhavari Bellutagi
03/20/2023, 4:26 PMDian Fu
03/21/2023, 1:51 AMwc.word_count(input_data) is void and it doesn’t return anything. You cannot call wc.word_count(input_data).add_sink(sink) , it ’s equal to None.add_sink .Vibhavari Bellutagi
03/21/2023, 1:12 PMDian Fu
03/22/2023, 2:25 AMsink implementations which could accept input elements and write them out to external storage.
• If you mean the sink used in the test case, you could refer to https://github.com/dianfu/pyflink-faq/blob/main/testing/test_datastream_api.py#L41.
• If you mean the sink in production job, you could refer to connector page: https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/connectors/datastream/overview/
It has given examples in each connector page how to use it in PyFlink.Vibhavari Bellutagi
03/25/2023, 11:53 AM