diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f344e62..f207675 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -130,7 +130,7 @@ and the [CodeQL Analysis YML](https://github.com/sr-murthy/fsrapiclient/blob/mai
## Versioning and Releases
-The [PyPI package](https://pypi.org/project/fsrapiclient/) is currently at version `0.3.0`.
+The [PyPI package](https://pypi.org/project/fsrapiclient/) is currently at version `0.4.0`.
There is currently no dedicated pipeline for releases - both [GitHub releases](https://github.com/sr-murthy/fsrapiclient/releases) and [PyPI packages](https://pypi.org/project/fsrapiclient) are published manually, but both have the same version tag.
diff --git a/README.md b/README.md
index a887b57..ad1d2c2 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@
A lightweight Python client library for the UK [Financial Services Register](https://register.fca.org.uk/s/) [RESTful API](https://register.fca.org.uk/Developer/s/).
-The [PyPI package](https://pypi.org/project/fsrapiclient) is currently at version `0.3.0`.
+The [PyPI package](https://pypi.org/project/fsrapiclient) is currently at version `0.4.0`.
The Financial Services Register, or FS Register, is a **public** database of all firms, individuals, funds, and other entities, that are either currently, or have been previously, authorised and/or regulated by the UK [Financial Conduct Authority (FCA)](https://www.fca.org.uk) and/or the [Prudential Regulation Authority (PRA)](http://bankofengland.co.uk/pra).
diff --git a/docs/sources/contributing.rst b/docs/sources/contributing.rst
index 8bf77d8..049573b 100644
--- a/docs/sources/contributing.rst
+++ b/docs/sources/contributing.rst
@@ -158,7 +158,7 @@ and the `CodeQL Analysis YML `_ is currently at version ``0.3.0``.
+The `PyPI package `_ is currently at version ``0.4.0``.
There is currently no dedicated pipeline for releases - both `GitHub releases `_ and `PyPI packages `_ are published manually, but both have the same version tag.
diff --git a/docs/sources/fs-register-api.rst b/docs/sources/fs-register-api.rst
index 9cefee6..65781ff 100644
--- a/docs/sources/fs-register-api.rst
+++ b/docs/sources/fs-register-api.rst
@@ -25,7 +25,7 @@ There are three main categories of resource about which information can be reque
- **individuals** - individuals associated with the type of firms described above, either current or past. Individuals in the register have unique **individual reference numbers (IRN)** and their endpoints usually take these as one of the parameters. They are described in more detail :ref:`here `.
- **funds** - investment funds or collective investment schemes (CIS),including subfunds of funds. Funds in the register have unique **product reference numbers (PRN)** and their endpoints usually take these as one of the parameters. They are described in more detail :ref:`here `.
-There is also a **common search** API endpoint that allows a search for any of these resources by a name substring and a corresponding type specification (firm, individual, or fund). This is described in more detail :ref:`here `.
+There are also search endpoints that allow a search for *(a)* any of these resources by a name substring and a corresponding type specification (firm, individual, or fund), or *(b)* `regulated markets `_. These are described in more detail :ref:`here `.
.. _fs-register-api.request-headers:
@@ -189,7 +189,7 @@ The common search API endpoint is a parameterised search endpoint which is summa
* - API Endpoint
- Request Method
- Search Parameters
- * - ``/V0.1/CommonSearch``
+ * - ``/V0.1/Search``
- GET
- ``q`` (resource name), ``type`` (resource type - ``'firm'``, ``'individual'``, or ``'fund'``)
@@ -197,7 +197,7 @@ Requests should be of the form:
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=resource_name&type=resource_type HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=resource_name&type=resource_type HTTP/1.1
For example, here are a few valid common search requests.
@@ -205,42 +205,48 @@ For example, here are a few valid common search requests.
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=Barclays+Bank+plc&type=firm HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=Barclays+Bank+plc&type=firm HTTP/1.1
* Common search for Hastings Insurance Services Limited (FRN #311492)
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=hastings+insurance+services&type=firm HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=hastings+insurance+services&type=firm HTTP/1.1
* Common search for all Natwest-related firms:
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=Natwest&type=firm HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=Natwest&type=firm HTTP/1.1
* Common search for a specific individual, Mark Carney (IRN #MXC29012):
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=mark+carney&type=individual HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=mark+carney&type=individual HTTP/1.1
* Common search for a generic individual name "John Smith", with multiple results:
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=John+Smith&type=individual HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=John+Smith&type=individual HTTP/1.1
* Common search for a specific fund, Jupiter Asia Pacific Income (PRN #635641):
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=jupiter+asia+pacific+income&type=fund HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=jupiter+asia+pacific+income&type=fund HTTP/1.1
* Common search for a specific fund, abrdn Multi-Asset Fund (PRN #637980):
.. code:: http
- GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=abrdn+multi-asset+fund&type=fund HTTP/1.1
+ GET https://register.fca.org.uk/services/V0.1/Search?q=abrdn+multi-asset+fund&type=fund HTTP/1.1
-For details and examples on calling this endpoint via this library see :ref:`this `.
+One particular type of common search-based endpoint that the API provides separately is for `regulated markets `_. These are special markets which are regulated by UK and/or EU/EEA financial legislation. API requests for regulated markets should look as below:
+
+.. code:: http
+
+ GET https://register.fca.org.uk/services/V0.1/CommonSearch?q=RM HTTP/1.1
+
+For details and examples on calling these endpoint via this library see :ref:`this `.
diff --git a/docs/sources/usage.rst b/docs/sources/usage.rst
index 910fc1e..1331066 100644
--- a/docs/sources/usage.rst
+++ b/docs/sources/usage.rst
@@ -63,7 +63,7 @@ The common search endpoint can be used via the :py:meth:`~fsrapiclient.api.FsrAp
.. code:: bash
- q=&type=
+ q=resource_name&type=resource_type
where ``q`` is a parameter whose value should be the name (or name substring) of a resource (firm, individual, or fund), and ``type`` is a parameter whose value should be one of ``'firm'``, ``'individual'``, ``'fund'``.
@@ -127,6 +127,48 @@ The response data as stored in the :py:attr:`~fsrapiclient.api.FsrApiResponse.fs
>>> client.common_search(urlencode({'q': 'natwest', 'type': 'individual'})).fsr_data
# Null
+.. _usage.regulated-markets:
+
+Regulated Markets
+-----------------
+
+The client implements a `regulated markets `_ search endpoint via the :py:meth:`~fsrapiclient.api.FsrApiClient.get_regulated_markets` method:
+
+.. code:: python
+
+ >>> c.get_regulated_markets().fsr_data
+
+ [{'Name': 'The London Metal Exchange',
+ 'TradingName': '',
+ 'Type of business or Individual': 'Exchange - RM',
+ 'Reference Number': '',
+ 'Status': '',
+ 'FirmURL': 'https://register.fca.org.uk/services/V0.1/Firm/'},
+ {'Name': 'ICE Futures Europe',
+ 'TradingName': '',
+ 'Type of business or Individual': 'Exchange - RM',
+ 'Reference Number': '',
+ 'Status': '',
+ 'FirmURL': 'https://register.fca.org.uk/services/V0.1/Firm/'},
+ {'Name': 'London Stock Exchange',
+ 'TradingName': '',
+ 'Type of business or Individual': 'Exchange - RM',
+ 'Reference Number': '',
+ 'Status': '',
+ 'FirmURL': 'https://register.fca.org.uk/services/V0.1/Firm/'},
+ {'Name': 'Aquis Stock Exchange Limited',
+ 'TradingName': 'ICAP Securities & Derivatives Exchange Limited',
+ 'Type of business or Individual': 'Exchange - RM',
+ 'Reference Number': '',
+ 'Status': '',
+ 'FirmURL': 'https://register.fca.org.uk/services/V0.1/Firm/'},
+ {'Name': 'Cboe Europe Equities Regulated Market',
+ 'TradingName': '',
+ 'Type of business or Individual': 'Exchange - RM',
+ 'Reference Number': '',
+ 'Status': '',
+ 'FirmURL': 'https://register.fca.org.uk/services/V0.1/Firm/'}]
+
.. _usage.searching-ref-numbers:
Searching for FRNs, IRNs and PRNs
diff --git a/pyproject.toml b/pyproject.toml
index f63d18d..1c154ea 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -38,6 +38,7 @@ keywords = [
"financial services",
"financial services register",
"prudential regulation authority",
+ "regulated markets",
"restful api",
"uk",
]
diff --git a/src/fsrapiclient/__version__.py b/src/fsrapiclient/__version__.py
index ecad360..7e443c5 100644
--- a/src/fsrapiclient/__version__.py
+++ b/src/fsrapiclient/__version__.py
@@ -1,2 +1,2 @@
-__version__ = "0.3.0"
+__version__ = "0.4.0"
diff --git a/src/fsrapiclient/api.py b/src/fsrapiclient/api.py
index c84a6da..216c2a4 100644
--- a/src/fsrapiclient/api.py
+++ b/src/fsrapiclient/api.py
@@ -331,7 +331,7 @@ def common_search(self, search_str: str) -> FsrApiResponse:
>>> client.common_search(urlencode({'q': 'Hastings Direct', 'type': 'firm'}))
"""
- url = f'{FSR_API_CONSTANTS.BASEURL.value}/{self.api_version}/Search?{search_str}'
+ url = f'{FSR_API_CONSTANTS.BASEURL.value}/Search?{search_str}'
try:
return FsrApiResponse(self.api_session.get(url))
@@ -352,7 +352,7 @@ def _search_ref_number(self, resource_name: str, resource_type: str) -> str:
/V0.1/Search?q=resource_name&type=resource_type
to perform a case-insensitive search for resources of type
- ``resource_type``in the FS Register on the given resource name
+ ``resource_type`` in the FS Register on the given resource name
substring.
Returns a non-null string of the resource ref. number if there is
@@ -564,8 +564,6 @@ def _get_resource_info(self, resource_ref_number: str, resource_type: str, modif
url = (
f'{FSR_API_CONSTANTS.BASEURL.value}'
'/'
- f'{self.api_version}'
- '/'
f'{resource_endpoint_base}'
'/'
f'{resource_ref_number}'
@@ -1518,6 +1516,84 @@ def get_fund_subfunds(self, prn: str) -> FsrApiResponse:
modifiers=('Subfund',)
)
+ def get_regulated_markets(self) -> FsrApiResponse:
+ """:py:class:`~fsrapiclient.api.FsrApiResponse` : Returns a response containing details of all current regulated markets, as defined in UK and EU / EEA financial services legislation.
+
+ For further information consult the API documentation:
+
+ https://register.fca.org.uk/Developer/s/
+
+ or the FCA glossary:
+
+ https://www.handbook.fca.org.uk/handbook/glossary/G978.html?date=2007-01-20
+
+ Returns
+ -------
+ FsrApiResponse
+ Wrapper of the API response object - there may be no data in
+ the response if the common search query produces no results.
+
+ Examples
+ --------
+ >>> import json, os
+ >>> client = FsrApiClient(os.environ['API_USERNAME'], os.environ['API_KEY'])
+ >>> res = client.get_regulated_markets()
+ >>> print(json.dumps(res.fsr_data, indent=True))
+ [
+ {
+ "Name": "The London Metal Exchange",
+ "TradingName": "",
+ "Type of business or Individual": "Exchange - RM",
+ "Reference Number": "",
+ "Status": "",
+ "FirmURL": "https://register.fca.org.uk/services/V0.1/Firm/"
+ },
+ {
+ "Name": "ICE Futures Europe",
+ "TradingName": "",
+ "Type of business or Individual": "Exchange - RM",
+ "Reference Number": "",
+ "Status": "",
+ "FirmURL": "https://register.fca.org.uk/services/V0.1/Firm/"
+ },
+ {
+ "Name": "London Stock Exchange",
+ "TradingName": "",
+ "Type of business or Individual": "Exchange - RM",
+ "Reference Number": "",
+ "Status": "",
+ "FirmURL": "https://register.fca.org.uk/services/V0.1/Firm/"
+ },
+ {
+ "Name": "Aquis Stock Exchange Limited",
+ "TradingName": "ICAP Securities & Derivatives Exchange Limited",
+ "Type of business or Individual": "Exchange - RM",
+ "Reference Number": "",
+ "Status": "",
+ "FirmURL": "https://register.fca.org.uk/services/V0.1/Firm/"
+ },
+ {
+ "Name": "Cboe Europe Equities Regulated Market",
+ "TradingName": "",
+ "Type of business or Individual": "Exchange - RM",
+ "Reference Number": "",
+ "Status": "",
+ "FirmURL": "https://register.fca.org.uk/services/V0.1/Firm/"
+ }
+ ]
+ """
+ url = (
+ f'{FSR_API_CONSTANTS.BASEURL.value}'
+ '/'
+ 'CommonSearch'
+ '?'
+ f'{urlencode({"q": "RM"})}'
+ )
+
+ return FsrApiResponse(
+ self.api_session.get(url)
+ )
+
if __name__ == "__main__": # pragma: no cover
# Doctest the module from the project root using
#
diff --git a/src/fsrapiclient/constants.py b/src/fsrapiclient/constants.py
index d5ca84f..8760e7f 100644
--- a/src/fsrapiclient/constants.py
+++ b/src/fsrapiclient/constants.py
@@ -16,16 +16,16 @@ class FSR_API_CONSTANTS(Enum):
Examples
--------
- >>> FSR_API_CONSTANTS.BASEURL.value
- 'https://register.fca.org.uk/services'
>>> FSR_API_CONSTANTS.API_VERSION.value
'V0.1'
+ >>> FSR_API_CONSTANTS.BASEURL.value
+ 'https://register.fca.org.uk/services/V0.1'
>>> FSR_API_CONSTANTS.RESOURCE_TYPES.value
{'firm': {'type_name': 'firm', 'endpoint_base': 'Firm'}, 'fund': {'type_name': 'fund', 'endpoint_base': 'CIS'}, 'individual': {'type_name': 'individual', 'endpoint_base': 'Individuals'}}
"""
- BASEURL = 'https://register.fca.org.uk/services'
API_VERSION = 'V0.1'
+ BASEURL = f'https://register.fca.org.uk/services/{API_VERSION}'
RESOURCE_TYPES = {
'firm': {'type_name': 'firm', 'endpoint_base': 'Firm'},
'fund': {'type_name': 'fund', 'endpoint_base': 'CIS'},
diff --git a/tests/units/test_api.py b/tests/units/test_api.py
index 223bdd3..8b13eb5 100644
--- a/tests/units/test_api.py
+++ b/tests/units/test_api.py
@@ -917,3 +917,16 @@ def test_fsr_api_client__get_fund_subfunds(self):
recv_response = test_client.get_fund_subfunds('1234567890')
assert recv_response.ok
assert not recv_response.fsr_data
+
+ def test_fsr_api_client__get_regulated_markets(self):
+ test_client = FsrApiClient(self._api_username, self._api_key)
+
+ # Covers the regulated markets API endpoint, which ATM returns a
+ # list of markets regulated by UK and/or EU/EEA financial legislation.
+ #
+ # We don't bother to check the exact list of markets returned by the
+ # endpoint, as this may change - it is enough to check that the endpoint
+ # should provide some data.
+ recv_response = test_client.get_regulated_markets()
+ assert recv_response.ok
+ assert recv_response.fsr_data
diff --git a/tests/units/test_constants.py b/tests/units/test_constants.py
index 728e12c..15f3b2f 100644
--- a/tests/units/test_constants.py
+++ b/tests/units/test_constants.py
@@ -11,8 +11,8 @@
class TestFsrApiConstants:
def test_fsr_api_constants(self):
- assert FSR_API_CONSTANTS.BASEURL.value == 'https://register.fca.org.uk/services'
assert FSR_API_CONSTANTS.API_VERSION.value == 'V0.1'
+ assert FSR_API_CONSTANTS.BASEURL.value == 'https://register.fca.org.uk/services/V0.1'
assert FSR_API_CONSTANTS.RESOURCE_TYPES.value == {
'firm': {'type_name': 'firm', 'endpoint_base': 'Firm'},
'fund': {'type_name': 'fund', 'endpoint_base': 'CIS'},