new: Allow to programatically create taxonomies

Add a jupiter notebook, bump taxonomies
pull/6/head
Raphaël Vinot 2018-07-06 17:49:06 +02:00
parent ba9be5f35d
commit 676392d97d
5 changed files with 226 additions and 5 deletions

2
.gitignore vendored
View File

@ -3,3 +3,5 @@ dist
pytaxonomies.egg-info
*.swp
*.pyc
.ipynb_checkpoints

View File

@ -0,0 +1,195 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Create a new taxonomy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pytaxonomies import Taxonomy, Predicate, Entry\n",
"\n",
"new_taxonomy = Taxonomy()\n",
"\n",
"new_taxonomy.name = \"false-positive\"\n",
"new_taxonomy.description = \"This taxonomy aims to ballpark the expected amount of false positives.\"\n",
"new_taxonomy.version = 1\n",
"new_taxonomy.expanded = \"False positive\"\n",
"\n",
"risk_predicate = Predicate()\n",
"\n",
"risk_predicate.predicate = 'risk'\n",
"risk_predicate.expanded = 'Risk'\n",
"risk_predicate.description = 'Risk of having false positives in the tagged value.'\n",
"\n",
"low = Entry()\n",
"low.value = 'low'\n",
"low.expanded = 'Low'\n",
"low.description = 'The risk of having false positives in the tagged value is low.'\n",
"low.numerical_value = 25\n",
"\n",
"\n",
"medium = Entry()\n",
"medium.value = 'medium'\n",
"medium.expanded = 'Medium'\n",
"medium.description = 'The risk of having false positives in the tagged value is medium.'\n",
"medium.numerical_value = 50\n",
"\n",
"high = Entry()\n",
"high.value = 'high'\n",
"high.expanded = 'High'\n",
"high.description = 'The risk of having false positives in the tagged value is high.'\n",
"high.numerical_value = 75\n",
"\n",
"risk_predicate.entries = {}\n",
"risk_predicate.entries['low'] = low\n",
"risk_predicate.entries['medium'] = medium\n",
"risk_predicate.entries['high'] = high\n",
"\n",
"new_taxonomy.predicates = {}\n",
"new_taxonomy.predicates['risk'] = risk_predicate"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Add a taxonomy in the repository"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import json\n",
"\n",
"root_json = Path('..', 'pytaxonomies', 'data', 'misp-taxonomies')\n",
"\n",
"with open(root_json / 'MANIFEST.json', encoding='utf8') as m:\n",
" manifest = json.load(m)\n",
"\n",
"# Just a failsafe in case the new taxonomy needs to be modified\n",
"is_update = False\n",
"for t in manifest['taxonomies']:\n",
" if t['name'] == new_taxonomy.name:\n",
" is_update = True\n",
" t['version'] = new_taxonomy.version\n",
" t['description'] = new_taxonomy.description \n",
"\n",
"if not is_update:\n",
" manifest['taxonomies'].append({'version': new_taxonomy.version, 'name': new_taxonomy.name, 'description': new_taxonomy.description})\n",
"\n",
"with open(root_json / 'MANIFEST.json', 'w', encoding='utf8') as m:\n",
" json.dump(manifest, m, indent=2, ensure_ascii=False)\n",
" \n",
"\n",
"if not (root_json / new_taxonomy.name).exists():\n",
" (root_json / new_taxonomy.name).mkdir()\n",
"\n",
"with open(root_json / new_taxonomy.name / 'machinetag.json', 'w', encoding='utf8') as m:\n",
" json.dump(new_taxonomy.to_dict(), m, indent=2, ensure_ascii=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Edit a taxonomy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pytaxonomies import Taxonomies\n",
"\n",
"from pytaxonomies import Taxonomy, Predicate, Entry\n",
"\n",
"taxonomies = Taxonomies()\n",
"\n",
"edited_taxonomy = taxonomies[\"false-positive\"]\n",
"\n",
"edited_taxonomy.predicates['risk'].entries['low'].numerical_value = 20"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Save the edited taxonomy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import json\n",
"\n",
"root_json = Path('..', 'pytaxonomies', 'data', 'misp-taxonomies')\n",
"\n",
"with open(root_json / 'MANIFEST.json', encoding='utf8') as m:\n",
" manifest = json.load(m)\n",
" \n",
"# Just a failsafe in case the new taxonomy needs to be modified\n",
"is_update = False\n",
"for t in manifest['taxonomies']:\n",
" if t['name'] == edited_taxonomy.name:\n",
" is_update = True\n",
" t['version'] += 1\n",
" edited_taxonomy.version = t['version']\n",
" t['description'] = edited_taxonomy.description\n",
"\n",
"if not is_update:\n",
" raise Exception(f'Taxonomy {edited_taxonomy.name} does not exists in the manifest.')\n",
"\n",
"with open(root_json / 'MANIFEST.json', 'w', encoding='utf8') as m:\n",
" json.dump(manifest, m, indent=2, ensure_ascii=False)\n",
"\n",
"with open(root_json / edited_taxonomy.name / 'machinetag.json', 'w', encoding='utf8') as m:\n",
" json.dump(edited_taxonomy.to_dict(), m, indent=2, ensure_ascii=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@ -1 +1 @@
from .api import Taxonomies, EncodeTaxonomies
from .api import Taxonomies, EncodeTaxonomies, Taxonomy, Predicate, Entry

View File

@ -30,7 +30,14 @@ class EncodeTaxonomies(JSONEncoder):
class Entry():
def __init__(self, entry):
def __init__(self, entry=None):
if not entry:
# We're creating a new one
self.expanded = None
self.colour = None
self.description = None
self.numerical_value = None
return
self.value = entry['value']
self.expanded = entry.get('expanded')
self.colour = entry.get('colour')
@ -58,7 +65,16 @@ class Entry():
class Predicate(collections.Mapping):
def __init__(self, predicate, entries):
def __init__(self, predicate=None, entries=None):
if not predicate and not entries:
# We're creating a new one
self.expanded = None
self.description = None
self.colour = None
self.exclusive = None
self.numerical_value = None
self.entries = {}
return
self.predicate = predicate['value']
self.expanded = predicate.get('expanded')
self.description = predicate.get('description')
@ -107,7 +123,15 @@ class Predicate(collections.Mapping):
class Taxonomy(collections.Mapping):
def __init__(self, taxonomy):
def __init__(self, taxonomy=None):
if not taxonomy:
# We're creating a new one
self.expanded = None
self.refs = None
self.type = None
self.exclusive = None
self.predicates = {}
return
self.taxonomy = taxonomy
self.name = self.taxonomy['namespace']
self.description = self.taxonomy['description']

@ -1 +1 @@
Subproject commit cc1910f1eef286f24fe2d5c3aefe88519d9d312c
Subproject commit ca76147d734b22fea663742886e97dfd8f654ee3