diff --git a/.python-txaio.metadata b/.python-txaio.metadata
new file mode 100644
index 0000000..0949d2c
--- /dev/null
+++ b/.python-txaio.metadata
@@ -0,0 +1 @@
+39fd03c3661260b490e046298d0887afa5e8fb7c SOURCES/txaio-22.2.1.tar.gz
diff --git a/SOURCES/await.patch b/SOURCES/await.patch
new file mode 100644
index 0000000..82e127d
--- /dev/null
+++ b/SOURCES/await.patch
@@ -0,0 +1,44 @@
+diff -ru txaio-2.10.0/test/test_gather.py txaio-2.10.0_patched/test/test_gather.py
+--- txaio-2.10.0/test/test_gather.py 2018-03-02 08:04:45.000000000 +0100
++++ txaio-2.10.0_patched/test/test_gather.py 2018-08-01 13:03:40.237465405 +0200
+@@ -26,7 +26,7 @@
+
+ import txaio
+
+-from util import await
++from util import await_completion
+
+
+ def test_gather_two(framework):
+@@ -61,7 +61,7 @@
+ txaio.add_callbacks(f2, done, error)
+
+ for f in [f0, f1, f2]:
+- await(f)
++ await_completion(f)
+
+ assert len(results) == 1
+ assert len(errors) == 0
+@@ -99,7 +99,7 @@
+ # out of "run_until_complete()" as well; fix util.py?
+ for f in [f0, f1, f2]:
+ try:
+- await(f)
++ await_completion(f)
+ except Exception:
+ pass
+
+Only in txaio-2.10.0_patched/test: .test_gather.py.swp
+diff -ru txaio-2.10.0/test/util.py txaio-2.10.0_patched/test/util.py
+--- txaio-2.10.0/test/util.py 2017-04-15 16:17:17.000000000 +0200
++++ txaio-2.10.0_patched/test/util.py 2018-08-01 13:02:30.099152902 +0200
+@@ -57,7 +57,7 @@
+ asyncio.gather(*asyncio.Task.all_tasks())
+
+
+-def await(future):
++def await_completion(future):
+ '''
+ Essentially just a way to call "run_until_complete" that becomes a
+ no-op if we're using Twisted.
+Only in txaio-2.10.0_patched/test: .util.py.swp
diff --git a/SOURCES/fix-doc-sphinx-1.4.8.patch b/SOURCES/fix-doc-sphinx-1.4.8.patch
new file mode 100644
index 0000000..81566a8
--- /dev/null
+++ b/SOURCES/fix-doc-sphinx-1.4.8.patch
@@ -0,0 +1,41 @@
+diff --git i/README.rst w/README.rst
+index f9084df..52e9769 100644
+--- i/README.rst
++++ w/README.rst
+@@ -1,10 +1,6 @@
+ txaio
+ =====
+
+-| |Version| |Downloads| |Build Status| |Coverage| |Docs|
+-
+---------------
+-
+ **txaio** is a helper library for writing code that runs unmodified on
+ both `Twisted `_ and `asyncio `_ / `Trollius `_.
+
+@@ -58,25 +54,3 @@ Code like the following can then run on *either* system:
+ # ...
+ txaio.resolve(f0, "value")
+ txaio.reject(f1, RuntimeError("it failed"))
+-
+-
+-.. |Version| image:: https://img.shields.io/pypi/v/txaio.svg
+- :target: https://pypi.python.org/pypi/txaio
+-
+-.. |Downloads| image:: https://img.shields.io/pypi/dm/txaio.svg
+- :target: https://pypi.python.org/pypi/txaio
+-
+-.. |GitHub Stars| image:: https://img.shields.io/github/stars/crossbario/txaio.svg?style=social&label=Star
+- :target: https://github.com/crossbario/txaio
+-
+-.. |Master Branch| image:: https://img.shields.io/badge/branch-master-orange.svg
+- :target: https://travis-ci.org/crossbario/txaio.svg?branch=master
+-
+-.. |Build Status| image:: https://travis-ci.org/crossbario/txaio.svg?branch=master
+- :target: https://travis-ci.org/crossbario/txaio
+-
+-.. |Coverage| image:: https://img.shields.io/codecov/c/github/crossbario/txaio/master.svg
+- :target: https://codecov.io/github/crossbario/txaio
+-
+-.. |Docs| image:: https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat
+- :target: http://txaio.readthedocs.org/en/latest/
diff --git a/SOURCES/fix-pytest3.patch b/SOURCES/fix-pytest3.patch
new file mode 100644
index 0000000..4e8cb3a
--- /dev/null
+++ b/SOURCES/fix-pytest3.patch
@@ -0,0 +1,21 @@
+From e48a9096c90686245d2e00f7957fd2058eb8101d Mon Sep 17 00:00:00 2001
+From: Julien Enselme
+Date: Sat, 1 Oct 2016 20:41:59 +0200
+Subject: [PATCH] Fix tests to run on pytest 3 and pytest 2
+
+---
+ test/conftest.py | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/test/conftest.py b/test/conftest.py
+index a79a27f..4a225c8 100644
+--- a/test/conftest.py
++++ b/test/conftest.py
+@@ -1,7 +1,5 @@
+ import pytest
+
+-pytest_plugins = ""
+-
+ # here's a little voodoo -- any generic tests depend on this 'framework'
+ # fixture, which (sneakily using internal-only APIs) ensures that each
+ # tests runs twice: once enabled for Twisted and once enabled for
diff --git a/SOURCES/python-txaio-skip-packaging-tests.patch b/SOURCES/python-txaio-skip-packaging-tests.patch
new file mode 100644
index 0000000..b495645
--- /dev/null
+++ b/SOURCES/python-txaio-skip-packaging-tests.patch
@@ -0,0 +1,10 @@
+--- test/test_packaging.py 2015-10-17 19:09:01.342981497 +0200
++++ test/test_packaging.py 2015-10-17 19:09:37.874402253 +0200
+@@ -34,6 +34,7 @@
+ import txaio
+
+
++@pytest.mark.skipif(True, reason='Not needed for RPM build')
+ def test_sdist():
+ if not hasattr(subprocess, 'check_output'):
+ pytest.skip()
diff --git a/SOURCES/run_once.patch b/SOURCES/run_once.patch
new file mode 100644
index 0000000..c6df2c0
--- /dev/null
+++ b/SOURCES/run_once.patch
@@ -0,0 +1,32 @@
+From ff27e91cd0e685add681850039ffc3cff35a06df Mon Sep 17 00:00:00 2001
+From: yatin
+Date: Wed, 20 Feb 2019 12:54:41 +0530
+Subject: [PATCH] Patch _run_once
+
+---
+ test/util.py | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/test/util.py b/test/util.py
+index 9f56778..8084b9c 100644
+--- a/test/util.py
++++ b/test/util.py
+@@ -42,9 +42,13 @@ def run_once():
+ import asyncio
+ if sys.version_info >= (3, 7):
+ # https://github.com/crossbario/txaio/issues/139
+- from _asyncio_test_utils import run_once as _run_once
++ def _run_once(loop):
++ loop.call_soon(loop.stop)
++ loop.run_forever()
+ else:
+- from asyncio.test_utils import run_once as _run_once
++ def _run_once(loop):
++ loop.call_soon(loop.stop)
++ loop.run_forever()
+ return _run_once(txaio.config.loop or asyncio.get_event_loop())
+
+ except ImportError:
+--
+2.17.1
+
diff --git a/SOURCES/skip-failing-test-python3.6.patch b/SOURCES/skip-failing-test-python3.6.patch
new file mode 100644
index 0000000..f466919
--- /dev/null
+++ b/SOURCES/skip-failing-test-python3.6.patch
@@ -0,0 +1,20 @@
+diff --git i/test/test_callback.py w/test/test_callback.py
+index 08d31e3..1bfc748 100644
+--- i/test/test_callback.py
++++ w/test/test_callback.py
+@@ -24,6 +24,7 @@
+ #
+ ###############################################################################
+
++import pytest
+ import txaio
+
+ from util import run_once
+@@ -59,6 +60,7 @@ def test_callback(framework):
+ assert results[0] == "it worked"
+
+
++@pytest.mark.skip(reason='Fails on 3.6')
+ def test_chained_callback(framework):
+ """
+ Chain two callbacks where the first one alters the value.
diff --git a/SPECS/python-txaio.spec b/SPECS/python-txaio.spec
new file mode 100644
index 0000000..da349f6
--- /dev/null
+++ b/SPECS/python-txaio.spec
@@ -0,0 +1,257 @@
+%global pypi_name txaio
+
+Name: python-%{pypi_name}
+Version: 22.2.1
+Release: 1%{?dist}
+Summary: Compatibility API between asyncio/Twisted/Trollius
+
+License: MIT
+URL: https://txaio.readthedocs.io/
+Source0: https://files.pythonhosted.org/packages/source/t/txaio/txaio-%{version}.tar.gz
+Patch0: python-txaio-skip-packaging-tests.patch
+# The test_utils module can no longer be imported from asyncio
+# and is undocumented intentionaly because it's private.
+# This is a hack that calls stop on the loop soon after calling run_forever().
+Patch2: run_once.patch
+BuildArch: noarch
+
+%description
+Helper library for writing code that runs unmodified on both Twisted and
+asyncio.
+
+%package -n python3-%{pypi_name}
+Summary: %{summary}
+BuildArch: noarch
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pytest
+BuildRequires: python3-pytest-cov
+BuildRequires: python3-mock
+BuildRequires: python3-six
+BuildRequires: python3-test
+BuildRequires: python3-enchant >= 1.6.6
+Requires: python3-six
+%{?python_provide:%python_provide python3-%{pypi_name}}
+
+%description -n python3-%{pypi_name}
+Helper library for writing code that runs unmodified on both Twisted and
+asyncio.
+
+%package doc
+Summary: Documentation for txaio
+
+BuildRequires: make
+BuildRequires: python3-sphinx
+BuildRequires: python3-sphinx_rtd_theme
+Requires: js-jquery
+
+%description doc
+Helper library for writing code that runs unmodified on both Twisted and
+asyncio. Documentation in html format.
+
+%prep
+%setup -qn %{pypi_name}-%{version}
+%patch0
+%patch2 -p1
+# Remove upstream's egg-info
+rm -rf %{pypi_name}.egg-info
+# README is just a symlink to index.rst. Using this file as README
+rm docs/index.rst
+cp -a README.rst docs/index.rst
+
+%build
+%py3_build
+# Build documentation
+cd docs && make html
+# Remove buildinfo
+rm -rf _build/html/.buildinfo
+# Unbundle jquery
+rm -f _build/html/_static/jquery.js
+ln -s /usr/share/javascript/jquery/latest/jquery.min.js _build/html/_static/jquery.js
+
+%install
+%py3_install
+
+%check
+%pytest -v test
+
+%files -n python3-%{pypi_name}
+%license LICENSE
+%doc README.rst
+%{python3_sitelib}/%{pypi_name}-%{version}-py%{python3_version}.egg-info/
+%{python3_sitelib}/%{pypi_name}/
+
+%files doc
+%license LICENSE
+%doc docs/_build/html
+
+%changelog
+* Fri Mar 04 2022 Fabian Affolter - 22.2.1-1
+- Update to latest upstream release 22.2.1 (closes rhbz#2057646)
+
+* Fri Jan 21 2022 Fedora Release Engineering - 21.2.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Tue Jul 27 2021 Fedora Release Engineering - 21.2.1-3
+- Second attempt - Rebuilt for
+ https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Fri Jun 04 2021 Python Maint - 21.2.1-2
+- Rebuilt for Python 3.10
+
+* Mon Feb 01 2021 Fabian Affolter - 21.2.1-1
+- Update to latest upstream release 21.2.1 (#1909406)
+
+* Wed Jan 27 2021 Fedora Release Engineering - 20.12.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Tue Dec 22 2020 Fabian Affolter - 20.12.1-1
+- Update to latest upstream release 20.12.1 (#1909406)
+
+* Wed Jul 29 2020 Fedora Release Engineering - 20.4.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Sat Jul 18 2020 Julien Enselme - 20.4.1-1
+- Update to 20.4.1
+
+* Tue May 26 2020 Miro Hrončok - 18.8.1-9
+- Rebuilt for Python 3.9
+
+* Thu Jan 30 2020 Fedora Release Engineering - 18.8.1-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Sat Oct 12 2019 Orion Poplawski - 18.8.1-7
+- Drop BR on python3-pep8
+- Use EL8 compatible coverage execution
+- Add BR python3-test for EL8 compatibility
+
+* Thu Oct 03 2019 Miro Hrončok - 18.8.1-6
+- Rebuilt for Python 3.8.0rc1 (#1748018)
+
+* Mon Aug 19 2019 Miro Hrončok - 18.8.1-5
+- Rebuilt for Python 3.8
+
+* Fri Jul 26 2019 Fedora Release Engineering - 18.8.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Sat Jul 13 2019 Julien Enselme - 18.8.1-3
+- Fix tests after pytest update.
+
+* Sat Mar 23 2019 Julien Enselme - 18.8.1-2
+- Remove Python 2 subpackage.
+
+* Wed Feb 20 2019 Yatin Karel - 18.8.1-1
+- Update to 18.8.1
+
+* Sat Feb 02 2019 Fedora Release Engineering - 18.7.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Wed Aug 01 2018 Julien Enselme - 18.7.1-1
+- Update to 18.7.1
+
+* Wed Aug 01 2018 Marcel Plch - 2.10.0-5
+- Patch for Python 3.7
+
+* Sat Jul 14 2018 Fedora Release Engineering - 2.10.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Tue Jun 19 2018 Miro Hrončok - 2.10.0-3
+- Rebuilt for Python 3.7
+
+* Tue May 08 2018 Miro Hrončok - 2.10.0-2
+- Remove unused build dependency on tox
+
+* Sun Apr 15 2018 Julien Enselme - 2.10.0-1
+- Update to 2.10.0
+
+* Tue Mar 06 2018 Julien Enselme - 2.9.0-1
+- Update to 2.9.0
+
+* Fri Feb 09 2018 Fedora Release Engineering - 2.8.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Wed Jan 31 2018 Iryna Shcherbina - 2.8.2-2
+- Update Python 2 dependency declarations to new packaging standards
+ (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3)
+
+* Wed Sep 06 2017 Julien Enselme - 2.8.2-1
+- Update to 2.8.2
+
+* Thu Jul 27 2017 Fedora Release Engineering - 2.8.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Sun Jul 23 2017 Julien Enselme - 2.8.1-1
+- Update to 2.8.1
+
+* Sat Jun 10 2017 Julien Enselme - 2.8.0-1
+- Update to 2.8.0
+
+* Sun May 07 2017 Julien Enselme - 2.7.1-1
+- Update to 2.7.1
+
+* Tue Apr 18 2017 Julien Enselme - 2.7.0-1
+- Update to 2.7.0
+
+* Wed Apr 05 2017 Julien Enselme - 2.6.2-1
+- Update to 2.6.2
+
+* Sat Feb 11 2017 Fedora Release Engineering - 2.5.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Mon Dec 26 2016 Julien Enselme - 2.5.2-1
+- Update to 2.5.2
+- Skip failing tests on Python 3.6
+
+* Mon Dec 19 2016 Miro Hrončok - 2.5.1-3
+- Rebuild for Python 3.6
+
+* Sat Oct 01 2016 Julien Enselme - 2.5.1-2
+- Fix tests for pytest3
+- Correct build of documentation with sphinx 1.4.8
+
+* Tue Jul 19 2016 Fedora Release Engineering - 2.5.1-2
+- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages
+
+* Mon May 16 2016 Julien Enselme - 2.5.1-1
+- Update to 2.5.1
+
+* Sat Feb 27 2016 Julien Enselme - 2.2.1-1
+- Update to 2.2.1
+
+* Thu Feb 04 2016 Fedora Release Engineering - 2.0.4-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Fri Nov 6 2015 Julien Enselme - 2.0.4-2
+- Rebuilt for python 3.5
+
+* Sat Oct 17 2015 Julien Enselme - 2.0.4-1
+- Update 2.0.4
+
+* Mon Sep 28 2015 Julien Enselme - 2.0.2-1
+- Update to 2.0.2
+
+* Sat Aug 15 2015 Julien Enselme - 1.0.3-2
+- Move python2 package in its own subpackage
+
+* Sat Aug 15 2015 Julien Enselme - 1.0.3-1
+- Update to 1.0.3
+
+* Sat Aug 8 2015 Julien Enselme - 1.0.2-1
+- Update to 1.0.2
+- Use %%py2_build, %%py3_build, %%py2_install and %%py2_install
+
+* Tue Aug 4 2015 Julien Enselme - 1.0.0-4
+- Correct sphinx theme name in BuildRequires
+
+* Thu Jul 30 2015 Julien Enselme - 1.0.0-3
+- Add provides for python2-txaio
+- Remove usage of python2 and python3 dirs
+- Unbundle jquery
+- Don't remove _sources of documentation
+
+* Fri Jul 24 2015 Julien Enselme - 1.0.0-2
+- Remove %%py3dir macro
+- Add CFLAGS in %%build
+
+* Sat Jul 18 2015 Julien Enselme - 1.0.0-1
+- Initial packaging