<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/pysim/+/23593">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">card_key_provider: Documentation with sphinx / autodoc<br><br>Change-Id: Ia41e14d643d452d92fc8d3c2fb9c4ac9021402e9<br>---<br>M docs/library.rst<br>M pySim/card_key_provider.py<br>2 files changed, 71 insertions(+), 15 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/93/23593/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/docs/library.rst b/docs/library.rst</span><br><span>index ae027ff..656a780 100644</span><br><span>--- a/docs/library.rst</span><br><span>+++ b/docs/library.rst</span><br><span>@@ -90,3 +90,9 @@</span><br><span> </span><br><span> .. automodule:: pySim.card_handler</span><br><span>    :members:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+pySim card_key_provider</span><br><span style="color: hsl(120, 100%, 40%);">+-----------------------</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+.. automodule:: pySim.card_key_provider</span><br><span style="color: hsl(120, 100%, 40%);">+   :members:</span><br><span>diff --git a/pySim/card_key_provider.py b/pySim/card_key_provider.py</span><br><span>index 80f93d0..b4e1daa 100644</span><br><span>--- a/pySim/card_key_provider.py</span><br><span>+++ b/pySim/card_key_provider.py</span><br><span>@@ -1,5 +1,14 @@</span><br><span> # coding=utf-8</span><br><span style="color: hsl(0, 100%, 40%);">-"""Abstraction of card related data that can be queried from external source."""</span><br><span style="color: hsl(120, 100%, 40%);">+"""Obtaining card parameters (mostly key data) from external source.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This module contains a base class and a concrete implementation of</span><br><span style="color: hsl(120, 100%, 40%);">+obtaining card key material (or other card-individual parameters) from</span><br><span style="color: hsl(120, 100%, 40%);">+an external data source.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This is used e.g. to keep PIN/PUK data in some file on disk, avoiding</span><br><span style="color: hsl(120, 100%, 40%);">+the need of manually entering the related card-individual data on every</span><br><span style="color: hsl(120, 100%, 40%);">+operation with pySim-shell.</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span> </span><br><span> # (C) 2021 by Sysmocom s.f.m.c. GmbH</span><br><span> # All Rights Reserved</span><br><span>@@ -23,16 +32,24 @@</span><br><span> </span><br><span> import csv</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-card_key_providers = List[CardKeyProvider]</span><br><span style="color: hsl(120, 100%, 40%);">+card_key_providers = List['CardKeyProvider']</span><br><span> </span><br><span> class CardKeyProvider(object):</span><br><span style="color: hsl(120, 100%, 40%);">+ """Abstract base class, not containing any concrete implementation."""</span><br><span> </span><br><span>     VALID_FIELD_NAMES = ['ICCID', 'ADM1', 'IMSI', 'PIN1', 'PIN2', 'PUK1', 'PUK2']</span><br><span> </span><br><span>    # check input parameters, but do nothing concrete yet</span><br><span style="color: hsl(0, 100%, 40%);">-   def get_data(self, fields:List[str]=[], key:str='ICCID', value:str="") -> Dict[str,str]:</span><br><span style="color: hsl(0, 100%, 40%);">-           """abstract implementation of get_data that only verifies the function parameters"""</span><br><span style="color: hsl(120, 100%, 40%);">+    def _verify_get_data(self, fields:List[str]=[], key:str='ICCID', value:str="") -> Dict[str,str]:</span><br><span style="color: hsl(120, 100%, 40%);">+         """Verify multiple fields for identified card.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+             Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 fields : list of valid field names such as 'ADM1', 'PIN1', ... which are to be obtained</span><br><span style="color: hsl(120, 100%, 40%);">+                       key : look-up key to identify card data, such as 'ICCID'</span><br><span style="color: hsl(120, 100%, 40%);">+                      value : value for look-up key to identify card data</span><br><span style="color: hsl(120, 100%, 40%);">+           Returns:</span><br><span style="color: hsl(120, 100%, 40%);">+                      dictionary of {field, value} strings for each requested field from 'fields'</span><br><span style="color: hsl(120, 100%, 40%);">+           """</span><br><span>           for f in fields:</span><br><span>                     if (f not in self.VALID_FIELD_NAMES):</span><br><span>                                raise ValueError("Requested field name '%s' is not a valid field name, valid field names are: %s" %</span><br><span>@@ -51,23 +68,34 @@</span><br><span>          return result.get(field)</span><br><span> </span><br><span>         def get(self, fields:List[str], key:str, value:str) -> Dict[str,str]:</span><br><span style="color: hsl(0, 100%, 40%);">-                """get fields from CSV file using a specified key/value pair"""</span><br><span style="color: hsl(120, 100%, 40%);">+         """Get multiple card-individual fields for identified card.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 fields : list of valid field names such as 'ADM1', 'PIN1', ... which are to be obtained</span><br><span style="color: hsl(120, 100%, 40%);">+                       key : look-up key to identify card data, such as 'ICCID'</span><br><span style="color: hsl(120, 100%, 40%);">+                      value : value for look-up key to identify card data</span><br><span style="color: hsl(120, 100%, 40%);">+           Returns:</span><br><span style="color: hsl(120, 100%, 40%);">+                      dictionary of {field, value} strings for each requested field from 'fields'</span><br><span style="color: hsl(120, 100%, 40%);">+           """</span><br><span>           pass</span><br><span> </span><br><span> class CardKeyProviderCsv(CardKeyProvider):</span><br><span style="color: hsl(0, 100%, 40%);">-  """card data class that allows the user to query against a specified CSV file"""</span><br><span style="color: hsl(120, 100%, 40%);">+        """Card key provider implementation that allows to query against a specified CSV file"""</span><br><span>       csv_file = None</span><br><span>      filename = None</span><br><span> </span><br><span>  def __init__(self, filename:str):</span><br><span style="color: hsl(120, 100%, 40%);">+             """</span><br><span style="color: hsl(120, 100%, 40%);">+            Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 filename : file name (path) of CSV file containing card-individual key/data</span><br><span style="color: hsl(120, 100%, 40%);">+           """</span><br><span>           self.csv_file = open(filename, 'r')</span><br><span>          if not self.csv_file:</span><br><span style="color: hsl(0, 100%, 40%);">-                   raise RuntimeError("Could not open CSV-File '%s'" % filename)</span><br><span style="color: hsl(120, 100%, 40%);">+                       raise RuntimeError("Could not open CSV file '%s'" % filename)</span><br><span>              self.filename = filename</span><br><span> </span><br><span>         def get(self, fields:List[str], key:str, value:str) -> Dict[str,str]:</span><br><span style="color: hsl(0, 100%, 40%);">-                """get fields from CSV file using a specified key/value pair"""</span><br><span style="color: hsl(0, 100%, 40%);">-           super().get_data(fields, key, value)</span><br><span style="color: hsl(120, 100%, 40%);">+          super()._verify_get_data(fields, key, value)</span><br><span> </span><br><span>             self.csv_file.seek(0)</span><br><span>                cr = csv.DictReader(self.csv_file)</span><br><span>@@ -88,17 +116,31 @@</span><br><span> </span><br><span> </span><br><span> def card_key_provider_register(provider:CardKeyProvider, provider_list=card_key_providers):</span><br><span style="color: hsl(0, 100%, 40%);">-        """Register a new card data provider"""</span><br><span style="color: hsl(120, 100%, 40%);">+ """Register a new card key provider.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ Args:</span><br><span style="color: hsl(120, 100%, 40%);">+         provider : the to-be-registered provider</span><br><span style="color: hsl(120, 100%, 40%);">+              provider_list : override the list of providers from the global default</span><br><span style="color: hsl(120, 100%, 40%);">+        """</span><br><span>   if not isinstance(provider, CardKeyProvider):</span><br><span>                raise ValueError("provider is not a card data provier")</span><br><span>    provider_list.append(provider)</span><br><span> </span><br><span> </span><br><span> def card_key_provider_get(fields, key:str, value:str, provider_list=card_key_providers) -> Dict[str,str]:</span><br><span style="color: hsl(0, 100%, 40%);">-  """Query all registered card data providers"""</span><br><span style="color: hsl(120, 100%, 40%);">+  """Query all registered card data providers for card-individual [key] data.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  Args:</span><br><span style="color: hsl(120, 100%, 40%);">+         fields : list of valid field names such as 'ADM1', 'PIN1', ... which are to be obtained</span><br><span style="color: hsl(120, 100%, 40%);">+               key : look-up key to identify card data, such as 'ICCID'</span><br><span style="color: hsl(120, 100%, 40%);">+              value : value for look-up key to identify card data</span><br><span style="color: hsl(120, 100%, 40%);">+           provider_list : override the list of providers from the global default</span><br><span style="color: hsl(120, 100%, 40%);">+        Returns:</span><br><span style="color: hsl(120, 100%, 40%);">+              dictionary of {field, value} strings for each requested field from 'fields'</span><br><span style="color: hsl(120, 100%, 40%);">+   """</span><br><span>   for p in provider_list:</span><br><span>              if not isinstance(p, CardKeyProvider):</span><br><span style="color: hsl(0, 100%, 40%);">-                  raise ValueError("provider list contains provider, which is not a card data provier")</span><br><span style="color: hsl(120, 100%, 40%);">+                       raise ValueError("provider list contains element which is not a card data provier")</span><br><span>                result = p.get(fields, key, value)</span><br><span>           if result:</span><br><span>                   return result</span><br><span>@@ -106,12 +148,20 @@</span><br><span> </span><br><span> </span><br><span> def card_key_provider_get_field(field:str, key:str, value:str, provider_list=card_key_providers) -> Optional[str]:</span><br><span style="color: hsl(0, 100%, 40%);">-  """Query all registered card data providers for a single field"""</span><br><span style="color: hsl(120, 100%, 40%);">+       """Query all registered card data providers for a single field.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      Args:</span><br><span style="color: hsl(120, 100%, 40%);">+         field : name valid field such as 'ADM1', 'PIN1', ... which is to be obtained</span><br><span style="color: hsl(120, 100%, 40%);">+          key : look-up key to identify card data, such as 'ICCID'</span><br><span style="color: hsl(120, 100%, 40%);">+              value : value for look-up key to identify card data</span><br><span style="color: hsl(120, 100%, 40%);">+           provider_list : override the list of providers from the global default</span><br><span style="color: hsl(120, 100%, 40%);">+        Returns:</span><br><span style="color: hsl(120, 100%, 40%);">+              dictionary of {field, value} strings for the requested field</span><br><span style="color: hsl(120, 100%, 40%);">+  """</span><br><span>   for p in provider_list:</span><br><span>              if not isinstance(p, CardKeyProvider):</span><br><span style="color: hsl(0, 100%, 40%);">-                  raise ValueError("provider list contains provider, which is not a card data provier")</span><br><span style="color: hsl(120, 100%, 40%);">+                       raise ValueError("provider list contains element which is not a card data provier")</span><br><span>                result = p.get_field(field, key, value)</span><br><span>              if result:</span><br><span>                   return result</span><br><span>        return None</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/pysim/+/23593">change 23593</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/pysim/+/23593"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: pysim </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ia41e14d643d452d92fc8d3c2fb9c4ac9021402e9 </div>
<div style="display:none"> Gerrit-Change-Number: 23593 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>