numberdb 0.0.1__tar.gz

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.
numberdb-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Benjamin Matschke
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,192 @@
1
+ Metadata-Version: 2.4
2
+ Name: numberdb
3
+ Version: 0.0.1
4
+ Summary: Look a number up in NumberDB and find out whether it is already known
5
+ Author: Benjamin Matschke
6
+ License: MIT
7
+ Project-URL: Homepage, https://numberdb.org
8
+ Project-URL: Source, https://github.com/numberdb/numberdb-website
9
+ Project-URL: Issues, https://github.com/numberdb/numberdb-website/issues
10
+ Keywords: mathematics,number theory,constants,sagemath,numberdb
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: license-file
22
+
23
+ # numberdb
24
+
25
+ Look a number up in [NumberDB](https://numberdb.org) and find out whether it is
26
+ already known, and where else it appears.
27
+
28
+ ```console
29
+ $ pip install numberdb
30
+ ```
31
+
32
+ ```python
33
+ >>> import numberdb
34
+ >>> for result in numberdb.search('pi'):
35
+ ... print(result.exact_text, '--', result.table.title)
36
+ 3.14159265358979323846264338327950288419716939937510582097494 -- Pi
37
+ 3.14159265358979323846264338327950288419716939937510582097494 -- Complete elliptic integral ...
38
+ ```
39
+
40
+ ## In SageMath
41
+
42
+ The same package, with one import line:
43
+
44
+ ```console
45
+ $ sage -pip install numberdb
46
+ ```
47
+
48
+ ```python
49
+ sage: import numberdb.sage as numberdb
50
+ sage: numberdb.search('{n: pi^n for n in [1..5]}')[0].value
51
+ 3.141592653589794?
52
+ ```
53
+
54
+ Everything below that line reads exactly as it would in plain Python — there is
55
+ no mode to set and nothing to pass at each call. `numberdb.sage` re-exports the
56
+ whole package, so it can stand in for it wholesale.
57
+
58
+ It uses the SageMath you already have and installs nothing. **There is no
59
+ `numberdb[sage]` extra, deliberately**: inside a full SageMath it would install
60
+ passagemath over the top, and the passagemath-flint wheel writes 383 files
61
+ under `sage/`, 349 of which already exist there — including compiled
62
+ extensions. pip reports no conflict, because Sage's own files belong to no pip
63
+ distribution.
64
+
65
+ If you have no Sage and still want Sage objects, install passagemath into a
66
+ *fresh* environment, never into an existing Sage.
67
+
68
+ Plain `import numberdb` never imports Sage at all, so it starts instantly; the
69
+ conversion is available per result as `.sage()` when you want it.
70
+
71
+ ## What you get back
72
+
73
+ `search()` returns a list of results, each carrying:
74
+
75
+ | | |
76
+ |---|---|
77
+ | `.value` | the number in plain Python (decoded on demand) |
78
+ | `.exact_text` | how the database writes it — the form to quote or paste back into a search |
79
+ | `.str_short` | a short form, comparable across results |
80
+ | `.table` | where it lives (`.tid`, `.title`, `.url`) |
81
+ | `.param` | which entry of that table it is |
82
+ | `.sage()` | the number as a Sage object |
83
+ | `.url()` | where to read about it |
84
+
85
+ `.value` is one of `int`, `Fraction`, `RealInterval`, `ComplexInterval`,
86
+ `PAdic` or `Polynomial`. A `PAdic` carries a `Fraction` — Q_p is not Z_p, so a
87
+ value of negative valuation such as 1/5 in Q_5 has no integer form — and its
88
+ `precision` is **absolute**: the ball is everything congruent to `value` modulo
89
+ `prime ** precision`, matching the `O(p^k)` in its string form. Exact values stay exact: integers are Python `int` (unbounded —
90
+ the database holds integers of over a thousand digits), rationals are
91
+ `Fraction`, and interval endpoints are exact `Fraction`s rather than rounded
92
+ floats. Converting to `float` is your decision, never an accident of transport.
93
+
94
+ ```python
95
+ >>> result.value
96
+ RealInterval(884279719003555/281474976710656, 7074237752028441/2251799813685248)
97
+ >>> float(result.value) # the midpoint, explicitly lossy
98
+ 3.141592653589793
99
+ ```
100
+
101
+ The search itself may have something to say — that it was capped, or that part
102
+ of the expression was rejected:
103
+
104
+ ```python
105
+ >>> results = numberdb.search('...')
106
+ >>> results.messages
107
+ ['We only show the first 100 results.']
108
+ ```
109
+
110
+ ### When the server is newer than the package
111
+
112
+ NumberDB will learn new kinds of number. An older package still returns every
113
+ result: values are decoded when you ask for them, so an unfamiliar one costs
114
+ you that value and nothing else, and its `exact_text` is there regardless.
115
+
116
+ ```python
117
+ >>> for result in numberdb.search('...'):
118
+ ... if result.is_readable:
119
+ ... use(result.value)
120
+ ... else:
121
+ ... print(result.exact_text) # still perfectly readable
122
+ ```
123
+
124
+ `results.unreadable` lists them, and every exception the package raises derives
125
+ from `numberdb.NumberDBError`, so one `except` covers it.
126
+
127
+ ## Rate limits and API keys
128
+
129
+ Anonymous use is rate limited. A key raises the limit:
130
+
131
+ Keep it out of your worksheet — a shared notebook should not carry its
132
+ author's key:
133
+
134
+ ```console
135
+ $ export NUMBERDB_API_KEY=...
136
+ ```
137
+
138
+ or, if you must set it in code:
139
+
140
+ ```python
141
+ >>> numberdb.configure(api_key='...')
142
+ ```
143
+
144
+ For more than one server or key in a process, use a client directly:
145
+
146
+ ```python
147
+ >>> client = numberdb.Client(api_key='...', base_url='http://localhost:8000/')
148
+ >>> numberdb.search('pi', client=client)
149
+ ```
150
+
151
+ Exceeding the limit raises `numberdb.RateLimited`, which carries `.retry_after`
152
+ in seconds when the server supplies it.
153
+
154
+ ## Pointing it somewhere else
155
+
156
+ The default is `https://numberdb.org`. Override it for a development server, or
157
+ a private instance:
158
+
159
+ ```console
160
+ $ export NUMBERDB_URL=http://localhost:8000
161
+ ```
162
+
163
+ ```python
164
+ >>> client = numberdb.Client(base_url='https://example.org/numberdb')
165
+ >>> numberdb.search('pi', client=client)
166
+ ```
167
+
168
+ A trailing slash is optional — a base URL with a path prefix keeps it either
169
+ way.
170
+
171
+ ## Other calls
172
+
173
+ ```python
174
+ >>> numberdb.table('T12') # a whole table, as stored
175
+ >>> numberdb.tag('Irrational') # the tables carrying a tag
176
+ ```
177
+
178
+ ## Why a package and not a file to copy
179
+
180
+ The API sends JSON, and turning it into numbers has to happen somewhere. Doing
181
+ it by hand is how the previous example client came to call `loads()` on
182
+ server-supplied bytes — which executes whatever those bytes say, handing code
183
+ execution to anyone able to answer the request. In this package decoding is a
184
+ fixed table: a response can select one of seven decoders and nothing else.
185
+
186
+ Being a package also means it is versioned. When the wire format changes, that
187
+ is a version bump and a clear error telling you to upgrade, rather than an
188
+ exception in the middle of your session.
189
+
190
+ ## Licence
191
+
192
+ GPL-3.0-or-later, matching NumberDB.
@@ -0,0 +1,170 @@
1
+ # numberdb
2
+
3
+ Look a number up in [NumberDB](https://numberdb.org) and find out whether it is
4
+ already known, and where else it appears.
5
+
6
+ ```console
7
+ $ pip install numberdb
8
+ ```
9
+
10
+ ```python
11
+ >>> import numberdb
12
+ >>> for result in numberdb.search('pi'):
13
+ ... print(result.exact_text, '--', result.table.title)
14
+ 3.14159265358979323846264338327950288419716939937510582097494 -- Pi
15
+ 3.14159265358979323846264338327950288419716939937510582097494 -- Complete elliptic integral ...
16
+ ```
17
+
18
+ ## In SageMath
19
+
20
+ The same package, with one import line:
21
+
22
+ ```console
23
+ $ sage -pip install numberdb
24
+ ```
25
+
26
+ ```python
27
+ sage: import numberdb.sage as numberdb
28
+ sage: numberdb.search('{n: pi^n for n in [1..5]}')[0].value
29
+ 3.141592653589794?
30
+ ```
31
+
32
+ Everything below that line reads exactly as it would in plain Python — there is
33
+ no mode to set and nothing to pass at each call. `numberdb.sage` re-exports the
34
+ whole package, so it can stand in for it wholesale.
35
+
36
+ It uses the SageMath you already have and installs nothing. **There is no
37
+ `numberdb[sage]` extra, deliberately**: inside a full SageMath it would install
38
+ passagemath over the top, and the passagemath-flint wheel writes 383 files
39
+ under `sage/`, 349 of which already exist there — including compiled
40
+ extensions. pip reports no conflict, because Sage's own files belong to no pip
41
+ distribution.
42
+
43
+ If you have no Sage and still want Sage objects, install passagemath into a
44
+ *fresh* environment, never into an existing Sage.
45
+
46
+ Plain `import numberdb` never imports Sage at all, so it starts instantly; the
47
+ conversion is available per result as `.sage()` when you want it.
48
+
49
+ ## What you get back
50
+
51
+ `search()` returns a list of results, each carrying:
52
+
53
+ | | |
54
+ |---|---|
55
+ | `.value` | the number in plain Python (decoded on demand) |
56
+ | `.exact_text` | how the database writes it — the form to quote or paste back into a search |
57
+ | `.str_short` | a short form, comparable across results |
58
+ | `.table` | where it lives (`.tid`, `.title`, `.url`) |
59
+ | `.param` | which entry of that table it is |
60
+ | `.sage()` | the number as a Sage object |
61
+ | `.url()` | where to read about it |
62
+
63
+ `.value` is one of `int`, `Fraction`, `RealInterval`, `ComplexInterval`,
64
+ `PAdic` or `Polynomial`. A `PAdic` carries a `Fraction` — Q_p is not Z_p, so a
65
+ value of negative valuation such as 1/5 in Q_5 has no integer form — and its
66
+ `precision` is **absolute**: the ball is everything congruent to `value` modulo
67
+ `prime ** precision`, matching the `O(p^k)` in its string form. Exact values stay exact: integers are Python `int` (unbounded —
68
+ the database holds integers of over a thousand digits), rationals are
69
+ `Fraction`, and interval endpoints are exact `Fraction`s rather than rounded
70
+ floats. Converting to `float` is your decision, never an accident of transport.
71
+
72
+ ```python
73
+ >>> result.value
74
+ RealInterval(884279719003555/281474976710656, 7074237752028441/2251799813685248)
75
+ >>> float(result.value) # the midpoint, explicitly lossy
76
+ 3.141592653589793
77
+ ```
78
+
79
+ The search itself may have something to say — that it was capped, or that part
80
+ of the expression was rejected:
81
+
82
+ ```python
83
+ >>> results = numberdb.search('...')
84
+ >>> results.messages
85
+ ['We only show the first 100 results.']
86
+ ```
87
+
88
+ ### When the server is newer than the package
89
+
90
+ NumberDB will learn new kinds of number. An older package still returns every
91
+ result: values are decoded when you ask for them, so an unfamiliar one costs
92
+ you that value and nothing else, and its `exact_text` is there regardless.
93
+
94
+ ```python
95
+ >>> for result in numberdb.search('...'):
96
+ ... if result.is_readable:
97
+ ... use(result.value)
98
+ ... else:
99
+ ... print(result.exact_text) # still perfectly readable
100
+ ```
101
+
102
+ `results.unreadable` lists them, and every exception the package raises derives
103
+ from `numberdb.NumberDBError`, so one `except` covers it.
104
+
105
+ ## Rate limits and API keys
106
+
107
+ Anonymous use is rate limited. A key raises the limit:
108
+
109
+ Keep it out of your worksheet — a shared notebook should not carry its
110
+ author's key:
111
+
112
+ ```console
113
+ $ export NUMBERDB_API_KEY=...
114
+ ```
115
+
116
+ or, if you must set it in code:
117
+
118
+ ```python
119
+ >>> numberdb.configure(api_key='...')
120
+ ```
121
+
122
+ For more than one server or key in a process, use a client directly:
123
+
124
+ ```python
125
+ >>> client = numberdb.Client(api_key='...', base_url='http://localhost:8000/')
126
+ >>> numberdb.search('pi', client=client)
127
+ ```
128
+
129
+ Exceeding the limit raises `numberdb.RateLimited`, which carries `.retry_after`
130
+ in seconds when the server supplies it.
131
+
132
+ ## Pointing it somewhere else
133
+
134
+ The default is `https://numberdb.org`. Override it for a development server, or
135
+ a private instance:
136
+
137
+ ```console
138
+ $ export NUMBERDB_URL=http://localhost:8000
139
+ ```
140
+
141
+ ```python
142
+ >>> client = numberdb.Client(base_url='https://example.org/numberdb')
143
+ >>> numberdb.search('pi', client=client)
144
+ ```
145
+
146
+ A trailing slash is optional — a base URL with a path prefix keeps it either
147
+ way.
148
+
149
+ ## Other calls
150
+
151
+ ```python
152
+ >>> numberdb.table('T12') # a whole table, as stored
153
+ >>> numberdb.tag('Irrational') # the tables carrying a tag
154
+ ```
155
+
156
+ ## Why a package and not a file to copy
157
+
158
+ The API sends JSON, and turning it into numbers has to happen somewhere. Doing
159
+ it by hand is how the previous example client came to call `loads()` on
160
+ server-supplied bytes — which executes whatever those bytes say, handing code
161
+ execution to anyone able to answer the request. In this package decoding is a
162
+ fixed table: a response can select one of seven decoders and nothing else.
163
+
164
+ Being a package also means it is versioned. When the wire format changes, that
165
+ is a version bump and a clear error telling you to upgrade, rather than an
166
+ exception in the middle of your session.
167
+
168
+ ## Licence
169
+
170
+ GPL-3.0-or-later, matching NumberDB.