<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def union(union_a, union_b):
 """Union of two vector layers. Issue https://github.com/inasafe/inasafe/issues/3186 :param union_a: The vector layer for the union. :type union_a: QgsVectorLayer :param union_b: The vector layer for the union. :type union_b: QgsVectorLayer :return: The clip vector layer. :rtype: QgsVectorLayer .. versionadded:: 4.0 """

    output_layer_name = union_steps['output_layer_name']
    output_layer_name = output_layer_name % (
        union_a.keywords['layer_purpose'],
        union_b.keywords['layer_purpose']
    )

    keywords_union_1 = union_a.keywords
    keywords_union_2 = union_b.keywords
    inasafe_fields_union_1 = keywords_union_1['inasafe_fields']
    inasafe_fields_union_2 = keywords_union_2['inasafe_fields']
    inasafe_fields = inasafe_fields_union_1
    inasafe_fields.update(inasafe_fields_union_2)

    parameters = {'INPUT': union_a,
                  'OVERLAY': union_b,
                  'OUTPUT': 'memory:'}

    # TODO implement callback through QgsProcessingFeedback object

    initialize_processing()

    feedback = create_processing_feedback()
    context = create_processing_context(feedback=feedback)
    result = processing.run('native:union', parameters, context=context)
    if result is None:
        raise ProcessingInstallationError

    union_layer = result['OUTPUT']
    union_layer.setName(output_layer_name)

    # use to avoid modifying original source
    union_layer.keywords = dict(union_a.keywords)
    union_layer.keywords['inasafe_fields'] = inasafe_fields
    union_layer.keywords['title'] = output_layer_name
    union_layer.keywords['layer_purpose'] = 'aggregate_hazard'
    union_layer.keywords['hazard_keywords'] = keywords_union_1.copy()
    union_layer.keywords['aggregation_keywords'] = keywords_union_2.copy()

    fill_hazard_class(union_layer)

    check_layer(union_layer)
    return union_layer