followthemoney 3.8.4__py3-none-any.whl → 4.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. followthemoney/__init__.py +30 -10
  2. followthemoney/cli/__init__.py +3 -12
  3. followthemoney/cli/aggregate.py +1 -1
  4. followthemoney/cli/cli.py +1 -1
  5. followthemoney/cli/exports.py +6 -2
  6. followthemoney/cli/mapping.py +6 -4
  7. followthemoney/cli/sieve.py +1 -1
  8. followthemoney/cli/statement.py +62 -0
  9. followthemoney/cli/util.py +2 -3
  10. followthemoney/compare.py +26 -16
  11. followthemoney/dataset/__init__.py +17 -0
  12. followthemoney/dataset/catalog.py +77 -0
  13. followthemoney/dataset/coverage.py +29 -0
  14. followthemoney/dataset/dataset.py +137 -0
  15. followthemoney/dataset/publisher.py +25 -0
  16. followthemoney/dataset/resource.py +30 -0
  17. followthemoney/dataset/util.py +58 -0
  18. followthemoney/entity.py +73 -0
  19. followthemoney/exc.py +6 -0
  20. followthemoney/export/common.py +3 -3
  21. followthemoney/export/csv.py +10 -12
  22. followthemoney/export/neo4j.py +1 -1
  23. followthemoney/export/rdf.py +57 -5
  24. followthemoney/graph.py +6 -4
  25. followthemoney/mapping/csv.py +6 -18
  26. followthemoney/mapping/sql.py +3 -4
  27. followthemoney/model.py +36 -9
  28. followthemoney/namespace.py +3 -1
  29. followthemoney/ontology.py +18 -16
  30. followthemoney/property.py +12 -15
  31. followthemoney/proxy.py +44 -65
  32. followthemoney/schema/Analyzable.yaml +2 -3
  33. followthemoney/schema/BankAccount.yaml +2 -3
  34. followthemoney/schema/Company.yaml +0 -6
  35. followthemoney/schema/Contract.yaml +0 -1
  36. followthemoney/schema/CryptoWallet.yaml +1 -1
  37. followthemoney/schema/Document.yaml +0 -6
  38. followthemoney/schema/Interval.yaml +7 -0
  39. followthemoney/schema/LegalEntity.yaml +6 -0
  40. followthemoney/schema/License.yaml +2 -0
  41. followthemoney/schema/Page.yaml +0 -1
  42. followthemoney/schema/Person.yaml +0 -5
  43. followthemoney/schema/Sanction.yaml +1 -0
  44. followthemoney/schema/Thing.yaml +0 -2
  45. followthemoney/schema/UserAccount.yaml +6 -3
  46. followthemoney/schema.py +27 -39
  47. followthemoney/statement/__init__.py +19 -0
  48. followthemoney/statement/entity.py +437 -0
  49. followthemoney/statement/serialize.py +245 -0
  50. followthemoney/statement/statement.py +256 -0
  51. followthemoney/statement/util.py +31 -0
  52. followthemoney/types/__init__.py +66 -23
  53. followthemoney/types/address.py +3 -3
  54. followthemoney/types/checksum.py +3 -7
  55. followthemoney/types/common.py +9 -14
  56. followthemoney/types/country.py +3 -7
  57. followthemoney/types/date.py +21 -11
  58. followthemoney/types/email.py +0 -4
  59. followthemoney/types/entity.py +5 -11
  60. followthemoney/types/gender.py +6 -10
  61. followthemoney/types/identifier.py +9 -3
  62. followthemoney/types/ip.py +5 -9
  63. followthemoney/types/json.py +2 -2
  64. followthemoney/types/language.py +3 -7
  65. followthemoney/types/mimetype.py +4 -8
  66. followthemoney/types/name.py +7 -8
  67. followthemoney/types/number.py +88 -6
  68. followthemoney/types/phone.py +4 -11
  69. followthemoney/types/string.py +4 -4
  70. followthemoney/types/topic.py +3 -7
  71. followthemoney/types/url.py +5 -10
  72. followthemoney/util.py +12 -13
  73. followthemoney/value.py +67 -0
  74. {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/METADATA +38 -34
  75. {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/RECORD +78 -69
  76. {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/entry_points.txt +1 -0
  77. {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/licenses/LICENSE +1 -0
  78. followthemoney/offshore.py +0 -48
  79. followthemoney/rdf.py +0 -9
  80. followthemoney/schema/Assessment.yaml +0 -32
  81. followthemoney/schema/Post.yaml +0 -42
  82. followthemoney/types/iban.py +0 -58
  83. followthemoney/types/registry.py +0 -52
  84. {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/WHEEL +0 -0
@@ -1,42 +0,0 @@
1
- Post:
2
- label: "Post"
3
- plural: "Posts"
4
- extends:
5
- - Interest
6
- matchable: false
7
- deprecated: true
8
- # cf. https://www.popoloproject.com/specs/post.html
9
- # But they're using it to define the post as an abstract thing, this
10
- # describes the interval in which it is held by an individual.
11
- description: >
12
- A post, role or position held by an individual within an organization
13
- or body. This describes the period for which the position is held,
14
- not the abstract concept of the post.
15
- featured:
16
- - holder
17
- - organization
18
- - role
19
- - startDate
20
- - endDate
21
- required:
22
- - holder
23
- caption:
24
- - summary
25
- - organization
26
- - role
27
- properties:
28
- holder:
29
- label: "Holder"
30
- reverse:
31
- name: posts
32
- label: "Posts held"
33
- type: entity
34
- range: Person
35
- organization:
36
- # This is a stub text version of the org, describing it by name.
37
- label: "Organization"
38
- type: string
39
- wikidataId:
40
- label: "Wikidata ID"
41
- hidden: true
42
- type: identifier
@@ -1,58 +0,0 @@
1
- from typing import Optional, TYPE_CHECKING
2
- from rigour.ids import IBAN
3
-
4
- from followthemoney.types.common import PropertyType
5
- from followthemoney.rdf import URIRef, Identifier
6
- from followthemoney.util import sanitize_text, defer as _
7
-
8
- if TYPE_CHECKING:
9
- from followthemoney.proxy import EntityProxy
10
-
11
-
12
- class IbanType(PropertyType):
13
- """An international bank account number, as defined in ISO 13616. IBANs are
14
- managed by SWIFT used in the European SEPA payment system.
15
-
16
- A notable aspect of IBANs is that they share a country prefix and validation
17
- mechanism, but the specific length of an IBAN is dependent on the country
18
- code defined in the first two characters: `NO8330001234567` and
19
- `CY21002001950000357001234567` are both valid values."""
20
-
21
- name = "iban"
22
- group = "ibans"
23
- label = _("IBAN")
24
- plural = _("IBANs")
25
- matchable = True
26
- pivot = True
27
- max_length = 64
28
-
29
- def validate(
30
- self, value: str, fuzzy: bool = False, format: Optional[str] = None
31
- ) -> bool:
32
- text = sanitize_text(value)
33
- if text is None:
34
- return False
35
- return IBAN.is_valid(text)
36
-
37
- def clean_text(
38
- self,
39
- text: str,
40
- fuzzy: bool = False,
41
- format: Optional[str] = None,
42
- proxy: Optional["EntityProxy"] = None,
43
- ) -> Optional[str]:
44
- """Create a more clean, but still user-facing version of an
45
- instance of the type."""
46
- return IBAN.normalize(text)
47
-
48
- def country_hint(self, value: str) -> str:
49
- return value[:2].lower()
50
-
51
- def rdf(self, value: str) -> Identifier:
52
- return URIRef(self.node_id(value))
53
-
54
- def node_id(self, value: str) -> str:
55
- return f"iban:{value.upper()}"
56
-
57
- def caption(self, value: str) -> str:
58
- return IBAN.format(value)
@@ -1,52 +0,0 @@
1
- from banal import ensure_list
2
- from typing import Iterable, Set, Dict, Type, Union, List, Optional
3
-
4
- from followthemoney.types.common import PropertyType
5
-
6
-
7
- class Registry(object):
8
- """This registry keeps the processing helpers for all property types
9
- in the system. They are instantiated as singletons when the system is first
10
- loaded. The registry can be used to get a type, which can itself then
11
- clean, validate or format values of that type."""
12
-
13
- def __init__(self) -> None:
14
- self.named: Dict[str, PropertyType] = {}
15
- self.matchable: Set[PropertyType] = set()
16
- self.types: Set[PropertyType] = set()
17
- self.groups: Dict[str, PropertyType] = {}
18
- self.pivots: Set[PropertyType] = set()
19
-
20
- def add(self, clazz: Type[PropertyType]) -> None:
21
- """Add a singleton class."""
22
- type_ = clazz()
23
- self.named[clazz.name] = type_
24
- self.types.add(type_)
25
- if type_.matchable:
26
- self.matchable.add(type_)
27
- if type_.pivot:
28
- self.pivots.add(type_)
29
- if type_.group is not None:
30
- self.groups[type_.group] = type_
31
-
32
- def get(self, name: Union[str, PropertyType]) -> Optional[PropertyType]:
33
- """For a given property type name, get its type object. This can also
34
- be used via getattr, e.g. ``registry.phone``."""
35
- # Allow transparent re-checking.
36
- if isinstance(name, PropertyType):
37
- return name
38
- return self.named.get(name)
39
-
40
- def get_types(
41
- self, names: Iterable[Union[str, PropertyType]]
42
- ) -> List[PropertyType]:
43
- """Get a list of all type names."""
44
- names = ensure_list(names)
45
- types = [self.get(n) for n in names]
46
- return [t for t in types if t is not None]
47
-
48
- def __getitem__(self, name: str) -> PropertyType:
49
- return self.named[name]
50
-
51
- def __getattr__(self, name: str) -> PropertyType:
52
- return self.named[name]