Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v0.4.0 #10

Merged
merged 4 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
2 changes: 1 addition & 1 deletion docs/sources/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ and the `CodeQL Analysis YML <https://github.com/sr-murthy/fsrapiclient/blob/mai
Versioning and Releases :fas:`upload`
=====================================

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.

Expand Down
28 changes: 17 additions & 11 deletions docs/sources/fs-register-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <fs-register-api.individual-requests>`.
- **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 <fs-register-api.fund-requests>`.

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 <fs-register-api.common-search-requests>`.
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 <https://www.handbook.fca.org.uk/handbook/glossary/G978.html?date=2007-01-20>`_. These are described in more detail :ref:`here <fs-register-api.common-search-requests>`.

.. _fs-register-api.request-headers:

Expand Down Expand Up @@ -189,58 +189,64 @@ 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'``)

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.

* Common search for Barclays Bank Plc (FRN #122702):

.. 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 <usage.common-search>`.
One particular type of common search-based endpoint that the API provides separately is for `regulated markets <https://www.handbook.fca.org.uk/handbook/glossary/G978.html?date=2007-01-20>`_. 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 <usage.common-search>`.
44 changes: 43 additions & 1 deletion docs/sources/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ The common search endpoint can be used via the :py:meth:`~fsrapiclient.api.FsrAp

.. code:: bash

q=<resource name>&type=<resource 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'``.

Expand Down Expand Up @@ -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 <https://www.handbook.fca.org.uk/handbook/glossary/G978.html?date=2007-01-20>`_ 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
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ keywords = [
"financial services",
"financial services register",
"prudential regulation authority",
"regulated markets",
"restful api",
"uk",
]
Expand Down
2 changes: 1 addition & 1 deletion src/fsrapiclient/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = "0.3.0"
__version__ = "0.4.0"

84 changes: 80 additions & 4 deletions src/fsrapiclient/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ def common_search(self, search_str: str) -> FsrApiResponse:
>>> client.common_search(urlencode({'q': 'Hastings Direct', 'type': 'firm'}))
<Response [200]>
"""
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))
Expand All @@ -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
Expand Down Expand Up @@ -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}'
Expand Down Expand Up @@ -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
#
Expand Down
6 changes: 3 additions & 3 deletions src/fsrapiclient/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'},
Expand Down
13 changes: 13 additions & 0 deletions tests/units/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/units/test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'},
Expand Down
Loading