-
Notifications
You must be signed in to change notification settings - Fork 20
change: uv ify the project #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,4 @@ | ||
| bin/__pycache__/ | ||
| lib/__pycache__/ | ||
| lib/cpeimport/__pycache__/ | ||
| **/__pycache__ | ||
| data/*.gz | ||
| data/*.tar | ||
| data/*.json | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 3.13 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,45 @@ | ||
| # syntax=docker/dockerfile:1 | ||
|
|
||
| FROM python:3.8-slim-buster | ||
| FROM alpine:latest | ||
|
|
||
| COPY . /app | ||
|
|
||
| RUN <<EOF | ||
| apk update | ||
| apk add py3-pip | ||
| pip install pipx | ||
| pipx install --global uv | ||
| EOF | ||
|
|
||
| # Disable development dependencies | ||
| ENV UV_NO_DEV=1 | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| COPY REQUIREMENTS REQUIREMENTS | ||
| RUN pip3 install -r REQUIREMENTS | ||
| RUN uv sync --locked | ||
|
|
||
| # configuration | ||
| COPY <<EOF /app/config/settings.yaml | ||
| server: | ||
| port: 8000 | ||
| valkey: | ||
| host: valkey | ||
| port: 6379 | ||
| db: 8 | ||
| cpe: | ||
| path: '/data/nvdcpe-2.0.tar' | ||
| source: 'https://nvd.nist.gov/feeds/json/cpe/2.0/nvdcpe-2.0.tar.gz' | ||
| EOF | ||
|
|
||
| # entrypoint script | ||
| COPY <<EOF entrypoint.sh | ||
| #!/bin/ash | ||
| set -e | ||
|
|
||
| COPY bin bin | ||
| COPY etc /etc | ||
| COPY lib lib | ||
| COPY docker/entrypoint.sh entrypoint.sh | ||
| uv run cpe-import | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This runs the import only once at startup.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wasn't already the case in the previous implementation ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussion moved to #20 (comment)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I am missing something here but AFAIK docker only runs the entrypoint, there is no systemd scheduling tasks. |
||
| uv run cpe-server | ||
| EOF | ||
|
|
||
| RUN mkdir /app/config | ||
| RUN chmod u+x entrypoint.sh | ||
|
|
||
| ENTRYPOINT ["/app/entrypoint.sh"] | ||
| ENTRYPOINT ["/app/entrypoint.sh"] | ||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| [project] | ||
| name = "cpe-guesser" | ||
| version = "0.1.0" | ||
| description = "Add your description here" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This appears to be a placeholder. Was it copied from a template or generated automatically?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix description here: 6e605a9 |
||
| readme = "README.md" | ||
| requires-python = ">=3.13" | ||
| dependencies = [ | ||
| "dynaconf>=3.2.12", | ||
| "falcon>=4.2.0", | ||
| "pydantic>=2.12.5", | ||
| "spectree>=2.0.1", | ||
| "valkey[libvalkey]>=6.1.1", | ||
| ] | ||
|
|
||
| [build-system] | ||
| requires = ["uv_build>=0.9.26,<0.10.0"] | ||
| build-backend = "uv_build" | ||
|
|
||
| [project.scripts] | ||
| cpe-import = "cpe_guesser.bin.importer:main" | ||
| cpe-lookup = "cpe_guesser.bin.lookup:main" | ||
| cpe-server = "cpe_guesser.bin.server:main" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,24 @@ | ||
| #!/usr/bin/env python3 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This prevents running the importer directly.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix there: f649298 |
||
| # -*- coding: utf-8 -*- | ||
|
|
||
| import argparse | ||
| import sys | ||
| import os | ||
| import valkey | ||
| import sys | ||
| import urllib.error | ||
|
|
||
| import valkey | ||
| from dynaconf import Dynaconf | ||
| from valkey.client import Valkey | ||
|
|
||
| sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) | ||
| from lib.cpeimport import CPEDownloader, NVDCPEHandler, XMLCPEHandler | ||
| from cpe_guesser.cpeimport import CPEDownloader, NVDCPEHandler, XMLCPEHandler | ||
|
|
||
| # Configuration | ||
| settings = Dynaconf(settings_files=["../config/settings.yaml"]) | ||
| cpe_path = settings.get("cpe.path", "./data/nvdcpe-2.0.tar") | ||
| cpe_source = settings.get( | ||
| "cpe.source", | ||
| "https://nvd.nist.gov/feeds/json/cpe/2.0/nvdcpe-2.0.tar.gz", | ||
| ) | ||
| valkey_host = settings.get("valkey.host", "127.0.0.1") | ||
| valkey_port = settings.get("valkey.port", 6379) | ||
| valkey_db = settings.get("valkey.db", 8) | ||
|
|
||
| rdb = valkey.Valkey(host=valkey_host, port=valkey_port, db=valkey_db) | ||
| def dbsize(rdb: Valkey) -> int: | ||
| dbsize = rdb.dbsize() | ||
| if isinstance(dbsize, int): | ||
| return dbsize | ||
| return 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| def main(): | ||
| argparser = argparse.ArgumentParser( | ||
| description="Initializes the Redis database with CPE dictionary." | ||
| ) | ||
|
|
@@ -45,7 +38,20 @@ | |
| ) | ||
| args = argparser.parse_args() | ||
|
|
||
| if not args.replace and rdb.dbsize() > 0: | ||
| # Configuration | ||
| settings = Dynaconf(settings_files=["../config/settings.yaml"]) | ||
| cpe_path = settings.get("cpe.path", "./data/nvdcpe-2.0.tar") | ||
| cpe_source = settings.get( | ||
| "cpe.source", | ||
| "https://nvd.nist.gov/feeds/json/cpe/2.0/nvdcpe-2.0.tar.gz", | ||
| ) | ||
| valkey_host = settings.get("valkey.host", "127.0.0.1") | ||
| valkey_port = settings.get("valkey.port", 6666) | ||
| valkey_db = settings.get("valkey.db", 8) | ||
|
|
||
| rdb = valkey.Valkey(host=valkey_host, port=valkey_port, db=valkey_db) | ||
|
|
||
| if not args.replace and dbsize(rdb) > 0: | ||
| print(f"Warning! The Redis database already has {rdb.dbsize()} keys.") | ||
| print("Use --replace if you want to flush the database and repopulate it.") | ||
| sys.exit(0) | ||
|
|
@@ -60,13 +66,14 @@ | |
| FileNotFoundError, | ||
| PermissionError, | ||
| ) as e: | ||
| print(f"Error: {e}") | ||
| sys.exit(1) | ||
|
|
||
| elif os.path.isfile(cpe_path): | ||
| print(f"Using existing file {cpe_path} ...") | ||
| cpe_file = cpe_path | ||
|
|
||
| if rdb.dbsize() > 0 and args.replace: | ||
| if rdb.dbsize() > 0 and args.replace: # ty:ignore[unsupported-operator] | ||
| print(f"Flushing {rdb.dbsize()} keys from the database...") | ||
| rdb.flushdb() | ||
|
|
||
|
|
@@ -87,3 +94,7 @@ | |
| handler.parse_file(cpe_file, label=label) | ||
|
|
||
| print(f"Done! {rdb.dbsize()} keys inserted.") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,12 @@ | ||
| #!/usr/bin/env python3 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This prevents running the lookup directly.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix there: f649298 |
||
| # -*- coding: utf-8 -*- | ||
|
|
||
| import argparse | ||
| import os | ||
| import sys | ||
| import json | ||
|
|
||
| runPath = os.path.dirname(os.path.realpath(__file__)) | ||
| sys.path.append(os.path.join(runPath, "..")) | ||
| from lib.cpeguesser import CPEGuesser | ||
| from cpe_guesser import CPEGuesser | ||
|
|
||
| if __name__ == "__main__": | ||
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser( | ||
| description="Find potential CPE names from a list of keyword(s) and return a JSON of the results" | ||
| ) | ||
|
|
@@ -30,12 +26,18 @@ | |
| args = parser.parse_args() | ||
|
|
||
| cpeGuesser = CPEGuesser() | ||
| r = cpeGuesser.guessCpe(args.word) | ||
| cpes = cpeGuesser.guessCpe(args.word) | ||
|
|
||
| if not args.unique: | ||
| print(json.dumps(r)) | ||
| print(json.dumps(cpes)) | ||
| else: | ||
| try: | ||
| r = r[:1][0][1] | ||
| except: | ||
| r = [] | ||
| r = [] | ||
| if len(cpes) > 0: | ||
| if len(cpes[0]) >= 2: | ||
| cpes = cpes[0][1] | ||
|
|
||
| print(json.dumps(r)) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,19 @@ | ||
| #!/usr/bin/env python3 | ||
| # -*- coding: utf-8 -*- | ||
|
|
||
| import os | ||
| import json | ||
| import sys | ||
| import falcon | ||
| from wsgiref.simple_server import make_server | ||
| import json | ||
|
|
||
| import falcon | ||
| from dynaconf import Dynaconf | ||
|
|
||
| from cpe_guesser import CPEGuesser | ||
|
|
||
| # Configuration | ||
| settings = Dynaconf(settings_files=["../config/settings.yaml"]) | ||
| port = settings.get("server.port", 8000) | ||
|
|
||
| runPath = os.path.dirname(os.path.realpath(__file__)) | ||
| sys.path.append(os.path.join(runPath, "..")) | ||
|
|
||
| from lib.cpeguesser import CPEGuesser | ||
|
|
||
|
|
||
| class Search: | ||
| def on_post(self, req, resp): | ||
|
|
@@ -59,14 +56,17 @@ def on_post(self, req, resp): | |
| return | ||
|
|
||
| cpeGuesser = CPEGuesser() | ||
| try: | ||
| r = cpeGuesser.guessCpe(q["query"])[:1][0][1] | ||
| except: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While broadly catching exceptions was not ideal, this change removes exception handling entirely.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are already lots of changes in the pipe for that part of the code so I will not include direct fixes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that the intent was to remove the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While broadly catching exceptions was not ideal, this change removes exception handling entirely, which may introduce new failure modes. |
||
| r = [] | ||
| cpes = cpeGuesser.guessCpe(q["query"])[:1][0][1] | ||
|
|
||
| r = [] | ||
| if len(cpes) > 0: | ||
| if len(cpes[0]) >= 2: | ||
| r = cpes[0][1] | ||
|
|
||
| resp.media = r | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| def main(): | ||
| app = falcon.App() | ||
| app.add_route("/search", Search()) | ||
| app.add_route("/unique", Unique()) | ||
|
|
@@ -80,3 +80,7 @@ def on_post(self, req, resp): | |
| sys.exit(1) | ||
| except KeyboardInterrupt: | ||
| sys.exit(0) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uvshould be able to manage Python versions without requiring the repository to pin an exact version.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Version pinning is admitted as a good practice as it is supposed to guarantee at least a working setup for the tools shipped by the project. If the version is not wanted, one is free to ignore it. Moreover Python version pinning is not used when using the package as dependency. Rather the package manager relies on the
requires-pythonfield in thepyproject.tomlfile. I can remove it, yet I don't really understand the motivation behind this removal.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file appears to follow a documented approach, as outlined in UV’s Python version files guide, so it doesn’t seem inherently problematic. My perspective may differ, as I tend to prioritize portability across environments rather than a fixed, containerized setup. This is more of a library-development mindset, whereas the cybersecurity community often focuses on a narrower, deployment-specific usage of these tools.