omoika 2.1.0__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.
- omoika-2.1.0/LICENSE +9 -0
- omoika-2.1.0/PKG-INFO +255 -0
- omoika-2.1.0/README.md +204 -0
- omoika-2.1.0/pyproject.toml +160 -0
- omoika-2.1.0/src/omoika/__init__.py +191 -0
- omoika-2.1.0/src/omoika/cli/__init__.py +30 -0
- omoika-2.1.0/src/omoika/cli/console.py +33 -0
- omoika-2.1.0/src/omoika/cli/display.py +181 -0
- omoika-2.1.0/src/omoika/cli/logging.py +123 -0
- omoika-2.1.0/src/omoika/cli/progress.py +166 -0
- omoika-2.1.0/src/omoika/compiler.py +358 -0
- omoika-2.1.0/src/omoika/deps.py +206 -0
- omoika-2.1.0/src/omoika/elements/__init__.py +21 -0
- omoika-2.1.0/src/omoika/elements/base.py +74 -0
- omoika-2.1.0/src/omoika/elements/displays.py +206 -0
- omoika-2.1.0/src/omoika/elements/inputs.py +109 -0
- omoika-2.1.0/src/omoika/errors.py +210 -0
- omoika-2.1.0/src/omoika/ipc_worker.py +520 -0
- omoika-2.1.0/src/omoika/messages.py +150 -0
- omoika-2.1.0/src/omoika/ob.py +871 -0
- omoika-2.1.0/src/omoika/output.py +179 -0
- omoika-2.1.0/src/omoika/plugins.py +832 -0
- omoika-2.1.0/src/omoika/repo_inspector.py +1238 -0
- omoika-2.1.0/src/omoika/results.py +227 -0
- omoika-2.1.0/src/omoika/runtime.py +173 -0
- omoika-2.1.0/src/omoika/sets.py +136 -0
- omoika-2.1.0/src/omoika/settings.py +310 -0
- omoika-2.1.0/src/omoika/types.py +238 -0
- omoika-2.1.0/src/omoika/utils.py +151 -0
omoika-2.1.0/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
Copyright 2023 jerlendds
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
omoika-2.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: omoika
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: The Omoika plugins framework for graph-based information analysis and offline local-first investigative workflows.
|
|
5
|
+
Keywords: osint,open source intelligence,transform-pipeline,intelligence,plugins,graph,crawl,crawling,web,scraping,security,reconnaissance,enrichment,entity,analysis,investigation,threat,attribution,cti,threat-hunting,recon,attack-surface,entity-resolution,knowledge-graph,plugin-framework,extensible,python-plugins,investigative-journalism,research-tools,digital-investigations,provenance,compliance,local-first,offline,browser-automation,maltego
|
|
6
|
+
Author-email: jerlendds <jerlendds@omoika.space>
|
|
7
|
+
Requires-Python: >=3.13
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Classifier: Framework :: AsyncIO
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Natural Language :: English
|
|
12
|
+
Classifier: Topic :: Software Development
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Development Status :: 4 - Beta
|
|
17
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Operating System :: MacOS
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
23
|
+
Classifier: Topic :: Security
|
|
24
|
+
Classifier: Topic :: System :: Archiving
|
|
25
|
+
Classifier: Topic :: System :: Networking :: Monitoring
|
|
26
|
+
Classifier: Topic :: Utilities
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: pydantic>=2.12.5
|
|
29
|
+
Requires-Dist: packaging>=21.0
|
|
30
|
+
Requires-Dist: httpx[http2]>=0.28.1
|
|
31
|
+
Requires-Dist: beautifulsoup4>=4.14.3
|
|
32
|
+
Requires-Dist: rich>=14.2.0
|
|
33
|
+
Requires-Dist: dulwich>=1.1.0
|
|
34
|
+
Requires-Dist: selenium>=4.39.0 ; extra == "all"
|
|
35
|
+
Requires-Dist: playwright>=1.57.0 ; extra == "all"
|
|
36
|
+
Requires-Dist: pytest>=9.0.2 ; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest-asyncio>=1.3.0 ; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff>=0.14.11 ; extra == "dev"
|
|
39
|
+
Requires-Dist: mypy>=1.19.0 ; extra == "dev"
|
|
40
|
+
Requires-Dist: black>=25.12.0 ; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest-cov>=7.0.0 ; extra == "dev"
|
|
42
|
+
Project-URL: Changelog, https://github.com/omoika/plugins/releases
|
|
43
|
+
Project-URL: Documentation, https://docs.omoika.space/
|
|
44
|
+
Project-URL: Homepage, https://omoika.space
|
|
45
|
+
Project-URL: Repository, https://github.com/omoika/omoika
|
|
46
|
+
Project-URL: Source, https://github.com/omoika/plugins
|
|
47
|
+
Project-URL: Tracker, https://github.com/omoika/omoika/issues
|
|
48
|
+
Provides-Extra: all
|
|
49
|
+
Provides-Extra: dev
|
|
50
|
+
|
|
51
|
+
## Introducing Omoika: Reloaded
|
|
52
|
+
|
|
53
|
+
<p>
|
|
54
|
+
<a href="https://github.com/omoika/omoika">
|
|
55
|
+
<img src="./watermark.svg" height="130px" alt="Logo">
|
|
56
|
+
</a>
|
|
57
|
+
|
|
58
|
+
> _I have no data yet. It is a capital mistake to theorize before one has data. Insensibly
|
|
59
|
+
> one begins to twist facts to suit theories, instead of theories to suit facts._
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
# The Omoika Plugins Framework
|
|
64
|
+
|
|
65
|
+
[](https://pypi.org/project/omoika/)
|
|
66
|
+
[](https://www.python.org/downloads/)
|
|
67
|
+
[](https://opensource.org/licenses/MIT)
|
|
68
|
+
|
|
69
|
+
The plugin framework for [Omoika](https://github.com/omoika/omoika), a graph-based OSINT platform for recon, OSINT investigations, link analysis, and more. Offline. Local-first workflows. No cloud dependency.
|
|
70
|
+
|
|
71
|
+
## Overview
|
|
72
|
+
|
|
73
|
+
Omoika's plugin system enables you to define **entities** (_nodes in the graph_) and **transforms** (_operations that create new entities from existing ones_). The framework provides:
|
|
74
|
+
|
|
75
|
+
- **Entity definitions** with rich metadata, icons, colors, and form elements
|
|
76
|
+
- **Transform decorators** with dependency management and version targeting
|
|
77
|
+
- **Result types** for subgraphs, custom edges, and file attachments
|
|
78
|
+
- **Field types** for semantic type-based transform matching
|
|
79
|
+
- **Settings framework** for persistent configuration
|
|
80
|
+
- **CLI tools** for development and integration
|
|
81
|
+
|
|
82
|
+
## Installation
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install omoika[all]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For development:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git clone https://github.com/omoika/plugins.git
|
|
92
|
+
cd plugins/
|
|
93
|
+
pip install -e ".[dev]"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Quick Start
|
|
97
|
+
|
|
98
|
+
### Define an Entity
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from omoika import Plugin
|
|
102
|
+
from omoika.elements import TextInput, CopyText
|
|
103
|
+
from omoika.types import FieldType
|
|
104
|
+
|
|
105
|
+
class EmailEntity(Plugin):
|
|
106
|
+
version = "1.0.0"
|
|
107
|
+
label = "Email"
|
|
108
|
+
icon = "mail"
|
|
109
|
+
color = "#3B82F6"
|
|
110
|
+
category = "Identity"
|
|
111
|
+
|
|
112
|
+
elements = [
|
|
113
|
+
TextInput(label="Email", icon="mail", field_type=FieldType.EMAIL),
|
|
114
|
+
CopyText(label="Domain"),
|
|
115
|
+
]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Create a Transform
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from omoika import transform, Entity, Edge
|
|
122
|
+
|
|
123
|
+
@transform(
|
|
124
|
+
target="email@>=1.0.0",
|
|
125
|
+
label="Extract Domain",
|
|
126
|
+
icon="world",
|
|
127
|
+
)
|
|
128
|
+
async def extract_domain(entity):
|
|
129
|
+
email = entity.email
|
|
130
|
+
domain = email.split("@")[1] if "@" in email else None
|
|
131
|
+
|
|
132
|
+
if domain:
|
|
133
|
+
return Entity(
|
|
134
|
+
data=DomainEntity.blueprint(domain=domain),
|
|
135
|
+
edge=Edge(label="has domain"),
|
|
136
|
+
)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Run a Transform
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
ob run -T '{"label": "email", "version": "1.0.0", "transform": "extract_domain", "data": {"email": "user@example.com"}}'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Documentation
|
|
146
|
+
|
|
147
|
+
| Guide | Description |
|
|
148
|
+
| ------------------------------------------ | --------------------------------------------------- |
|
|
149
|
+
| [Getting Started](docs/getting-started.md) | Installation, project setup, and first plugin |
|
|
150
|
+
| [Plugins & Entities](docs/plugins.md) | Defining entities with the Plugin class |
|
|
151
|
+
| [Transforms](docs/transforms.md) | Creating transforms with the `@transform` decorator |
|
|
152
|
+
| [Elements](docs/elements.md) | Input and display elements for entity forms |
|
|
153
|
+
| [Field Types](docs/types.md) | Semantic types for fields and type-based matching |
|
|
154
|
+
| [Settings](docs/settings.md) | Transform configuration and persistence |
|
|
155
|
+
| [CLI Reference](docs/cli.md) | Command-line interface documentation |
|
|
156
|
+
| [API Reference](docs/api-reference.md) | Complete API documentation |
|
|
157
|
+
|
|
158
|
+
## Key Concepts
|
|
159
|
+
|
|
160
|
+
### Plugins & Entities
|
|
161
|
+
|
|
162
|
+
Every node type in the graph is defined as a `Plugin` subclass. Plugins are automatically registered when defined:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
class IPAddress(Plugin):
|
|
166
|
+
version = "1.0.0"
|
|
167
|
+
label = "IP Address"
|
|
168
|
+
elements = [TextInput(label="IP", field_type=FieldType.IP_ADDRESS)]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Transforms
|
|
172
|
+
|
|
173
|
+
Transforms operate on entities to produce new entities. They target specific entity versions:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
@transform(target="ip_address@>=1.0.0", label="GeoIP Lookup", deps=["geoip2"])
|
|
177
|
+
async def geoip_lookup(entity):
|
|
178
|
+
# Transform logic
|
|
179
|
+
return Entity(data=Location.blueprint(city="..."))
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Result Types
|
|
183
|
+
|
|
184
|
+
Transforms return `Entity`, `Edge`, `File`, or `Subgraph` objects:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
return Entity(
|
|
188
|
+
data=TargetEntity.blueprint(field="value"),
|
|
189
|
+
edge=Edge(label="discovered", color="#22C55E"),
|
|
190
|
+
files=[File(path="/tmp/report.pdf")],
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Project Structure
|
|
195
|
+
|
|
196
|
+
For plugin development and registry submissions, organize your code as:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
my-plugins-repo/
|
|
200
|
+
├── entities/
|
|
201
|
+
│ ├── email.py
|
|
202
|
+
│ ├── domain.py
|
|
203
|
+
│ └── ip_address.py
|
|
204
|
+
└── transforms/
|
|
205
|
+
├── email_transforms.py
|
|
206
|
+
├── domain_transforms.py
|
|
207
|
+
├── network_traceroute_transform.py
|
|
208
|
+
└── network_transforms.py
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Load plugins via:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from omoika import load_plugins_fs
|
|
215
|
+
load_plugins_fs("/path/to/my-plugins", "my_plugins")
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## CLI Commands
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# List entities and transforms
|
|
222
|
+
ob ls entities
|
|
223
|
+
ob ls transforms -L email
|
|
224
|
+
|
|
225
|
+
# Run a transform
|
|
226
|
+
ob transform '{"label": "email", "version": "1.0.0", "transform": "to_domain", "data": {...}}'
|
|
227
|
+
|
|
228
|
+
# Get entity blueprints
|
|
229
|
+
ob blueprints -L email
|
|
230
|
+
|
|
231
|
+
# Initialize a new plugins project
|
|
232
|
+
ob init
|
|
233
|
+
|
|
234
|
+
# Sync manifest and README metadata after repo changes
|
|
235
|
+
ob sync
|
|
236
|
+
|
|
237
|
+
# Compile JSON entity to Python
|
|
238
|
+
ob compile entity.json -O entity.py
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Requirements
|
|
242
|
+
|
|
243
|
+
- Python 3.13+
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT License, see [LICENSE](LICENSE) for details.
|
|
248
|
+
|
|
249
|
+
## Links
|
|
250
|
+
|
|
251
|
+
<!-- - [Documentation](https://docs.omoika.space/) -->
|
|
252
|
+
|
|
253
|
+
- [Omoika Application](https://github.com/omoika/omoika)
|
|
254
|
+
- [Issue Tracker](https://github.com/omoika/omoika/issues)
|
|
255
|
+
|
omoika-2.1.0/README.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
## Introducing Omoika: Reloaded
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<a href="https://github.com/omoika/omoika">
|
|
5
|
+
<img src="./watermark.svg" height="130px" alt="Logo">
|
|
6
|
+
</a>
|
|
7
|
+
|
|
8
|
+
> _I have no data yet. It is a capital mistake to theorize before one has data. Insensibly
|
|
9
|
+
> one begins to twist facts to suit theories, instead of theories to suit facts._
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# The Omoika Plugins Framework
|
|
14
|
+
|
|
15
|
+
[](https://pypi.org/project/omoika/)
|
|
16
|
+
[](https://www.python.org/downloads/)
|
|
17
|
+
[](https://opensource.org/licenses/MIT)
|
|
18
|
+
|
|
19
|
+
The plugin framework for [Omoika](https://github.com/omoika/omoika), a graph-based OSINT platform for recon, OSINT investigations, link analysis, and more. Offline. Local-first workflows. No cloud dependency.
|
|
20
|
+
|
|
21
|
+
## Overview
|
|
22
|
+
|
|
23
|
+
Omoika's plugin system enables you to define **entities** (_nodes in the graph_) and **transforms** (_operations that create new entities from existing ones_). The framework provides:
|
|
24
|
+
|
|
25
|
+
- **Entity definitions** with rich metadata, icons, colors, and form elements
|
|
26
|
+
- **Transform decorators** with dependency management and version targeting
|
|
27
|
+
- **Result types** for subgraphs, custom edges, and file attachments
|
|
28
|
+
- **Field types** for semantic type-based transform matching
|
|
29
|
+
- **Settings framework** for persistent configuration
|
|
30
|
+
- **CLI tools** for development and integration
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install omoika[all]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For development:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/omoika/plugins.git
|
|
42
|
+
cd plugins/
|
|
43
|
+
pip install -e ".[dev]"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### Define an Entity
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from omoika import Plugin
|
|
52
|
+
from omoika.elements import TextInput, CopyText
|
|
53
|
+
from omoika.types import FieldType
|
|
54
|
+
|
|
55
|
+
class EmailEntity(Plugin):
|
|
56
|
+
version = "1.0.0"
|
|
57
|
+
label = "Email"
|
|
58
|
+
icon = "mail"
|
|
59
|
+
color = "#3B82F6"
|
|
60
|
+
category = "Identity"
|
|
61
|
+
|
|
62
|
+
elements = [
|
|
63
|
+
TextInput(label="Email", icon="mail", field_type=FieldType.EMAIL),
|
|
64
|
+
CopyText(label="Domain"),
|
|
65
|
+
]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Create a Transform
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from omoika import transform, Entity, Edge
|
|
72
|
+
|
|
73
|
+
@transform(
|
|
74
|
+
target="email@>=1.0.0",
|
|
75
|
+
label="Extract Domain",
|
|
76
|
+
icon="world",
|
|
77
|
+
)
|
|
78
|
+
async def extract_domain(entity):
|
|
79
|
+
email = entity.email
|
|
80
|
+
domain = email.split("@")[1] if "@" in email else None
|
|
81
|
+
|
|
82
|
+
if domain:
|
|
83
|
+
return Entity(
|
|
84
|
+
data=DomainEntity.blueprint(domain=domain),
|
|
85
|
+
edge=Edge(label="has domain"),
|
|
86
|
+
)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Run a Transform
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
ob run -T '{"label": "email", "version": "1.0.0", "transform": "extract_domain", "data": {"email": "user@example.com"}}'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
| Guide | Description |
|
|
98
|
+
| ------------------------------------------ | --------------------------------------------------- |
|
|
99
|
+
| [Getting Started](docs/getting-started.md) | Installation, project setup, and first plugin |
|
|
100
|
+
| [Plugins & Entities](docs/plugins.md) | Defining entities with the Plugin class |
|
|
101
|
+
| [Transforms](docs/transforms.md) | Creating transforms with the `@transform` decorator |
|
|
102
|
+
| [Elements](docs/elements.md) | Input and display elements for entity forms |
|
|
103
|
+
| [Field Types](docs/types.md) | Semantic types for fields and type-based matching |
|
|
104
|
+
| [Settings](docs/settings.md) | Transform configuration and persistence |
|
|
105
|
+
| [CLI Reference](docs/cli.md) | Command-line interface documentation |
|
|
106
|
+
| [API Reference](docs/api-reference.md) | Complete API documentation |
|
|
107
|
+
|
|
108
|
+
## Key Concepts
|
|
109
|
+
|
|
110
|
+
### Plugins & Entities
|
|
111
|
+
|
|
112
|
+
Every node type in the graph is defined as a `Plugin` subclass. Plugins are automatically registered when defined:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
class IPAddress(Plugin):
|
|
116
|
+
version = "1.0.0"
|
|
117
|
+
label = "IP Address"
|
|
118
|
+
elements = [TextInput(label="IP", field_type=FieldType.IP_ADDRESS)]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Transforms
|
|
122
|
+
|
|
123
|
+
Transforms operate on entities to produce new entities. They target specific entity versions:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
@transform(target="ip_address@>=1.0.0", label="GeoIP Lookup", deps=["geoip2"])
|
|
127
|
+
async def geoip_lookup(entity):
|
|
128
|
+
# Transform logic
|
|
129
|
+
return Entity(data=Location.blueprint(city="..."))
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Result Types
|
|
133
|
+
|
|
134
|
+
Transforms return `Entity`, `Edge`, `File`, or `Subgraph` objects:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
return Entity(
|
|
138
|
+
data=TargetEntity.blueprint(field="value"),
|
|
139
|
+
edge=Edge(label="discovered", color="#22C55E"),
|
|
140
|
+
files=[File(path="/tmp/report.pdf")],
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Project Structure
|
|
145
|
+
|
|
146
|
+
For plugin development and registry submissions, organize your code as:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
my-plugins-repo/
|
|
150
|
+
├── entities/
|
|
151
|
+
│ ├── email.py
|
|
152
|
+
│ ├── domain.py
|
|
153
|
+
│ └── ip_address.py
|
|
154
|
+
└── transforms/
|
|
155
|
+
├── email_transforms.py
|
|
156
|
+
├── domain_transforms.py
|
|
157
|
+
├── network_traceroute_transform.py
|
|
158
|
+
└── network_transforms.py
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Load plugins via:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from omoika import load_plugins_fs
|
|
165
|
+
load_plugins_fs("/path/to/my-plugins", "my_plugins")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## CLI Commands
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# List entities and transforms
|
|
172
|
+
ob ls entities
|
|
173
|
+
ob ls transforms -L email
|
|
174
|
+
|
|
175
|
+
# Run a transform
|
|
176
|
+
ob transform '{"label": "email", "version": "1.0.0", "transform": "to_domain", "data": {...}}'
|
|
177
|
+
|
|
178
|
+
# Get entity blueprints
|
|
179
|
+
ob blueprints -L email
|
|
180
|
+
|
|
181
|
+
# Initialize a new plugins project
|
|
182
|
+
ob init
|
|
183
|
+
|
|
184
|
+
# Sync manifest and README metadata after repo changes
|
|
185
|
+
ob sync
|
|
186
|
+
|
|
187
|
+
# Compile JSON entity to Python
|
|
188
|
+
ob compile entity.json -O entity.py
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Requirements
|
|
192
|
+
|
|
193
|
+
- Python 3.13+
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT License, see [LICENSE](LICENSE) for details.
|
|
198
|
+
|
|
199
|
+
## Links
|
|
200
|
+
|
|
201
|
+
<!-- - [Documentation](https://docs.omoika.space/) -->
|
|
202
|
+
|
|
203
|
+
- [Omoika Application](https://github.com/omoika/omoika)
|
|
204
|
+
- [Issue Tracker](https://github.com/omoika/omoika/issues)
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["flit_core >=3.2,<4"]
|
|
3
|
+
build-backend = "flit_core.buildapi"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "omoika"
|
|
7
|
+
authors = [
|
|
8
|
+
{name = "jerlendds", email = "jerlendds@omoika.space"},
|
|
9
|
+
]
|
|
10
|
+
description = "The Omoika plugins framework for graph-based information analysis and offline local-first investigative workflows."
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
license = {text = "MIT"}
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Framework :: AsyncIO",
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Natural Language :: English",
|
|
17
|
+
"Topic :: Software Development",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Development Status :: 4 - Beta",
|
|
22
|
+
"Intended Audience :: End Users/Desktop",
|
|
23
|
+
"Operating System :: Microsoft :: Windows",
|
|
24
|
+
"Operating System :: POSIX :: Linux",
|
|
25
|
+
"Operating System :: MacOS",
|
|
26
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
27
|
+
"Topic :: Scientific/Engineering :: Information Analysis",
|
|
28
|
+
"Topic :: Security",
|
|
29
|
+
"Topic :: System :: Archiving",
|
|
30
|
+
"Topic :: System :: Networking :: Monitoring",
|
|
31
|
+
"Topic :: Utilities"
|
|
32
|
+
]
|
|
33
|
+
keywords = ["osint", "open source intelligence", "transform-pipeline", "intelligence", "plugins", "graph", "crawl", "crawling", "web", "scraping", "security", "reconnaissance","enrichment", "entity", "analysis", "investigation", "threat", "attribution", "cti", "threat-hunting", "recon", "attack-surface", "entity-resolution", "knowledge-graph", "plugin-framework", "extensible", "python-plugins", "investigative-journalism", "research-tools", "digital-investigations", "provenance", "compliance", "local-first", "offline", "browser-automation", "maltego"]
|
|
34
|
+
requires-python = ">=3.13"
|
|
35
|
+
dynamic = ["version"]
|
|
36
|
+
|
|
37
|
+
dependencies = [
|
|
38
|
+
"pydantic>=2.12.5",
|
|
39
|
+
"packaging>=21.0",
|
|
40
|
+
"httpx[http2]>=0.28.1",
|
|
41
|
+
"beautifulsoup4>=4.14.3",
|
|
42
|
+
"rich>=14.2.0",
|
|
43
|
+
"dulwich>=1.1.0",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.optional-dependencies]
|
|
47
|
+
# Development dependencies
|
|
48
|
+
dev = [
|
|
49
|
+
"pytest>=9.0.2",
|
|
50
|
+
"pytest-asyncio>=1.3.0",
|
|
51
|
+
"ruff>=0.14.11",
|
|
52
|
+
"mypy>=1.19.0",
|
|
53
|
+
"black>=25.12.0",
|
|
54
|
+
"pytest-cov>=7.0.0",
|
|
55
|
+
]
|
|
56
|
+
# Browser automation, used by some default Omoika plugins
|
|
57
|
+
all = [
|
|
58
|
+
"selenium>=4.39.0",
|
|
59
|
+
"playwright>=1.57.0",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[dependency-groups]
|
|
63
|
+
dev = [
|
|
64
|
+
"pytest>=9.0.2",
|
|
65
|
+
"pytest-asyncio>=1.3.0",
|
|
66
|
+
"ruff>=0.14.11",
|
|
67
|
+
"mypy>=1.19.0",
|
|
68
|
+
"black>=25.12.0",
|
|
69
|
+
"pytest-cov>=7.0.0",
|
|
70
|
+
"selenium>=4.39.0",
|
|
71
|
+
"playwright>=1.57.0",
|
|
72
|
+
"pydantic>=2.12.5",
|
|
73
|
+
"packaging>=21.0",
|
|
74
|
+
"httpx[http2]>=0.28.1",
|
|
75
|
+
"beautifulsoup4>=4.14.3",
|
|
76
|
+
"rich>=14.2.0",
|
|
77
|
+
"dulwich>=1.1.0",
|
|
78
|
+
"pyinstaller>=6.19.0",
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
[project.urls]
|
|
82
|
+
Homepage = "https://omoika.space"
|
|
83
|
+
Documentation = "https://docs.omoika.space/"
|
|
84
|
+
Repository = "https://github.com/omoika/omoika"
|
|
85
|
+
Source = "https://github.com/omoika/plugins"
|
|
86
|
+
Tracker = "https://github.com/omoika/omoika/issues"
|
|
87
|
+
Changelog = "https://github.com/omoika/plugins/releases"
|
|
88
|
+
|
|
89
|
+
[project.scripts]
|
|
90
|
+
ob = "omoika.ob:main"
|
|
91
|
+
|
|
92
|
+
[tool.flit.module]
|
|
93
|
+
name = "omoika"
|
|
94
|
+
|
|
95
|
+
[tool.ruff]
|
|
96
|
+
line-length = 120
|
|
97
|
+
target-version = "py311"
|
|
98
|
+
|
|
99
|
+
[tool.ruff.lint]
|
|
100
|
+
select = ["E", "F", "W", "I", "UP", "B", "C4"]
|
|
101
|
+
ignore = ["E501", "B008"]
|
|
102
|
+
|
|
103
|
+
[tool.mypy]
|
|
104
|
+
python_version = "3.13"
|
|
105
|
+
warn_return_any = true
|
|
106
|
+
warn_unused_ignores = true
|
|
107
|
+
disallow_untyped_defs = false
|
|
108
|
+
check_untyped_defs = true
|
|
109
|
+
|
|
110
|
+
[tool.pytest.ini_options]
|
|
111
|
+
asyncio_mode = "auto"
|
|
112
|
+
testpaths = ["tests"]
|
|
113
|
+
addopts = "-v"
|
|
114
|
+
pythonpath = ["src"]
|
|
115
|
+
markers = [
|
|
116
|
+
"integration: marks as integration test",
|
|
117
|
+
"slow: marks tests as slow",
|
|
118
|
+
"unit: fast offline tests",
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
[tool.black]
|
|
122
|
+
line-length = 120
|
|
123
|
+
target-version = ['py311', 'py312']
|
|
124
|
+
|
|
125
|
+
[tool.coverage.run]
|
|
126
|
+
branch = true
|
|
127
|
+
source = ["src/omoika"]
|
|
128
|
+
|
|
129
|
+
[tool.coverage.report]
|
|
130
|
+
exclude_lines = [
|
|
131
|
+
"pragma: no cover",
|
|
132
|
+
"def __repr__",
|
|
133
|
+
"raise NotImplementedError",
|
|
134
|
+
"if TYPE_CHECKING:",
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
[tool.bandit]
|
|
138
|
+
exclude_dirs = ["build", "dist", "tests", "scripts"]
|
|
139
|
+
number = 4
|
|
140
|
+
recursive = true
|
|
141
|
+
targets = "src"
|
|
142
|
+
|
|
143
|
+
[tool.pyright]
|
|
144
|
+
include = ["src"]
|
|
145
|
+
exclude = [
|
|
146
|
+
"**/node_modules",
|
|
147
|
+
"**/__pycache__",
|
|
148
|
+
]
|
|
149
|
+
pythonVersion = "3.13"
|
|
150
|
+
pythonPlatform = "Linux"
|
|
151
|
+
typeCheckingMode = "basic"
|
|
152
|
+
reportMissingImports = true
|
|
153
|
+
reportMissingTypeStubs = false
|
|
154
|
+
|
|
155
|
+
[tool.hatch.build.targets.sdist.force-include]
|
|
156
|
+
"bin/ob.py" = "omoika/ob.py"
|
|
157
|
+
|
|
158
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
159
|
+
"bin/ob.py" = "omoika/ob.py"
|
|
160
|
+
|