Skip to content
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

Setup processing of zip files #7

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Changelog
=========

- :release:`0.2.0 <6th April 2023>`
- :feature:`6` Setup analyzing

- :release:`0.1.0 <3rd April 2023>`
- :feature:`1` Initialize package
2 changes: 0 additions & 2 deletions requirements/requirements-tests.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@

pytest
pytest-randomly

httpx # for fastapi.testclient.TestClient
27 changes: 0 additions & 27 deletions requirements/requirements-tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,6 @@
#
# pip-compile requirements/requirements-tests.in
#
anyio==4.3.0
# via
# -c requirements/requirements.txt
# httpx
certifi==2024.2.2
# via
# -c requirements/requirements.txt
# httpcore
# httpx
h11==0.14.0
# via
# -c requirements/requirements.txt
# httpcore
httpcore==1.0.5
# via httpx
httpx==0.27.0
# via -r requirements/requirements-tests.in
idna==3.6
# via
# -c requirements/requirements.txt
# anyio
# httpx
iniconfig==2.0.0
# via pytest
packaging==24.0
Expand All @@ -38,8 +16,3 @@ pytest==8.2.0
# pytest-randomly
pytest-randomly==3.15.0
# via -r requirements/requirements-tests.in
sniffio==1.3.1
# via
# -c requirements/requirements.txt
# anyio
# httpx
1 change: 1 addition & 0 deletions requirements/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
uvicorn[standard]
fastapi
pydantic-settings
httpx

# Metrics
sentry-sdk[fastapi]
22 changes: 18 additions & 4 deletions requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,34 @@ annotated-types==0.6.0
# via pydantic
anyio==4.3.0
# via
# httpx
# starlette
# watchfiles
certifi==2024.2.2
# via sentry-sdk
# via
# httpcore
# httpx
# sentry-sdk
click==8.1.7
# via uvicorn
fastapi==0.110.3
# via
# -r requirements/requirements.in
# sentry-sdk
h11==0.14.0
# via uvicorn
# via
# httpcore
# uvicorn
httpcore==1.0.5
# via httpx
httptools==0.6.1
# via uvicorn
httpx==0.27.0
# via -r requirements/requirements.in
idna==3.6
# via anyio
# via
# anyio
# httpx
pydantic==2.6.4
# via
# fastapi
Expand All @@ -41,7 +53,9 @@ pyyaml==6.0.1
sentry-sdk[fastapi]==2.0.1
# via -r requirements/requirements.in
sniffio==1.3.1
# via anyio
# via
# anyio
# httpx
starlette==0.37.2
# via fastapi
typing-extensions==4.10.0
Expand Down
2 changes: 1 addition & 1 deletion src/zipalyzer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""An API for analyzing zip files."""

__version__ = "0.1.0"
__version__ = "0.2.0"
30 changes: 30 additions & 0 deletions src/zipalyzer/files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Handle files and file contents."""

from hashlib import sha256
from io import BytesIO
from urllib.parse import unquote
from zipfile import ZipFile

import httpx

from zipalyzer.models.zip_information import File


async def get_zip_contents(path: str) -> dict[str, bytes]:
"""Get zip contents."""
async with httpx.AsyncClient() as client:
response = await client.get(url=unquote(path))

Check failure

Code scanning / CodeQL

Full server-side request forgery Critical

The full URL of this request depends on a
user-provided value
.
zip_file = ZipFile(BytesIO(response.content))
return {name: zip_file.read(name) for name in zip_file.namelist()}


def process_zip_contents(files: dict[str, bytes]) -> list[File]:
"""Process zip file contents."""
return [
File(
name=name,
contents=contents,
sha256_hash=sha256(contents).hexdigest(),
)
for name, contents in files.items()
]
12 changes: 12 additions & 0 deletions src/zipalyzer/models/zip_information.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Zip information models."""

from pydantic.dataclasses import dataclass


@dataclass
class File:
"""A file in a zip."""

name: str
contents: bytes
sha256_hash: str
2 changes: 2 additions & 0 deletions src/zipalyzer/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from fastapi.middleware.cors import CORSMiddleware

from zipalyzer.metadata.routes import router as router_metadata
from zipalyzer.zips.routes import router as router_zips

from . import __version__
from .constants import GIT_SHA, Sentry
Expand Down Expand Up @@ -32,3 +33,4 @@
)

app.include_router(router_metadata)
app.include_router(router_zips)
1 change: 1 addition & 0 deletions src/zipalyzer/zips/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Routes for zip handling."""
15 changes: 15 additions & 0 deletions src/zipalyzer/zips/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Routes for zip handling."""

from fastapi import APIRouter

from zipalyzer.files import get_zip_contents, process_zip_contents
from zipalyzer.models.zip_information import File

router = APIRouter(prefix="/zips", tags=["Zips"])


@router.get("/{path:path}", summary="Get zip information")
async def zip_info(path: str) -> list[File]:
"""Get zip information."""
contents = await get_zip_contents(path)
return process_zip_contents(contents)
1 change: 0 additions & 1 deletion tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from http import HTTPStatus

from fastapi.testclient import TestClient

from zipalyzer import __version__
from zipalyzer.server import app

Expand Down