From a7afadd476531503a8fcd236d2023f3f4d844e4c Mon Sep 17 00:00:00 2001 From: Francesco Frassinelli Date: Sat, 3 Aug 2024 18:56:29 +0200 Subject: [PATCH] Dependencies update and refactoring --- .dockerignore | 6 - .gitignore | 172 +++++++++++++++++ Dockerfile | 18 +- README.md | 27 ++- docker-compose.yml | 5 + poetry.lock | 247 ------------------------ pyproject.toml | 35 ++-- src/gpapconv/__init__.py | 1 + gpapconv.py => src/gpapconv/gpapconv.py | 27 ++- {web => src/gpapconv}/index.html | 0 queries.sql => src/gpapconv/queries.sql | 4 +- 11 files changed, 235 insertions(+), 307 deletions(-) delete mode 100644 .dockerignore create mode 100644 docker-compose.yml delete mode 100644 poetry.lock create mode 100644 src/gpapconv/__init__.py rename gpapconv.py => src/gpapconv/gpapconv.py (59%) rename {web => src/gpapconv}/index.html (100%) rename queries.sql => src/gpapconv/queries.sql (97%) diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index dd1ea47..0000000 --- a/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -.git/ -.gitignore -.dockerignore -__pycache__ -LICENSE -README.md diff --git a/.gitignore b/.gitignore index 749ccda..ad4a1f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,176 @@ +# Created by https://www.toptal.com/developers/gitignore/api/python +# Edit at https://www.toptal.com/developers/gitignore?templates=python + +### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +# End of https://www.toptal.com/developers/gitignore/api/python diff --git a/Dockerfile b/Dockerfile index 8204219..ddf04e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,6 @@ -FROM python:3.7-slim -LABEL maintainer="fraph24@gmail.com" - -WORKDIR /src -ADD poetry.lock pyproject.toml ./ - -RUN pip install poetry && \ - poetry install --no-root --no-dev - -ADD . . - +FROM python:3.11-alpine AS base +RUN --mount=type=bind,target=/pkg,rw \ + --mount=type=cache,target=/root/.cache/pip \ + pip install /pkg EXPOSE 8000 - -CMD ["/usr/local/bin/poetry", "run", "uvicorn", "--host", "0.0.0.0", "gpapconv:app"] +CMD ["uvicorn", "--host", "0.0.0.0", "gpapconv:app"] diff --git a/README.md b/README.md index 4372743..ea5570a 100644 --- a/README.md +++ b/README.md @@ -4,28 +4,27 @@ Geopaparazzi to OSM XML and GeoJSON converter Demo: https://gpapconv.frafra.eu/ -## Dependencies +## Technologies - [Python 3](https://www.python.org/) - [FastAPI](https://fastapi.tiangolo.com/) - [Uvicorn](https://www.uvicorn.org/) - - [Poetry](poetry.eustace.io/) - [sqlite](https://sqlite.org/) ## Setup -### uwsgi +### Classic -``` -$ poetry install --no-root --no-dev -$ poetry run uvicorn gpapconv:app +```bash +python3 -m venv venv +source venv/bin/activate +pip install -e . ``` -### Docker image +### Docker -``` -$ docker build --tag=gpapconv . -$ docker run --publish 8000:8000 --detach gpapconv +```bash +docker compose up --build ``` ## How to use @@ -38,12 +37,12 @@ Open http://localhost:8000. From gpap to OSM XML: -``` -$ curl -X POST -F "file=@geopaparazzi.gpap" http://localhost:8000/gpap2osm +```bash +curl -X POST -F "file=@geopaparazzi.gpap" http://localhost:8000/gpap2osm ``` From gpap to OSM GeoJSON: -``` -$ curl -X POST -F "file=@geopaparazzi.gpap" http://localhost:8000/gpap2geojson +```bash +curl -X POST -F "file=@geopaparazzi.gpap" http://localhost:8000/gpap2geojson ``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1757d53 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,5 @@ +services: + gpapconv: + build: . + ports: + - 8000:8000 \ No newline at end of file diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index e22bed4..0000000 --- a/poetry.lock +++ /dev/null @@ -1,247 +0,0 @@ -[[package]] -category = "main" -description = "File support for asyncio." -name = "aiofiles" -optional = false -python-versions = "*" -version = "0.4.0" - -[[package]] -category = "main" -description = "Easy SQL in Python" -name = "anosql" -optional = false -python-versions = "*" -version = "1.0.2" - -[[package]] -category = "main" -description = "Composable command line interface toolkit" -name = "click" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "7.1.2" - -[[package]] -category = "main" -description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -name = "fastapi" -optional = false -python-versions = ">=3.6" -version = "0.49.2" - -[package.dependencies] -pydantic = ">=0.32.2,<2.0.0" -starlette = "0.12.9" - -[package.extras] -all = ["requests", "aiofiles", "jinja2", "python-multipart", "itsdangerous", "pyyaml", "graphene", "ujson", "email-validator", "uvicorn", "async-exit-stack", "async-generator"] -dev = ["pyjwt", "passlib", "autoflake", "flake8", "uvicorn", "graphene"] -doc = ["mkdocs", "mkdocs-material", "markdown-include"] -test = ["pytest (>=4.0.0)", "pytest-cov", "mypy", "black", "isort", "requests", "email-validator", "sqlalchemy", "peewee", "databases", "orjson", "async-exit-stack", "async-generator", "python-multipart", "aiofiles", "ujson"] - -[[package]] -category = "main" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -name = "h11" -optional = false -python-versions = "*" -version = "0.9.0" - -[[package]] -category = "main" -description = "A collection of framework independent HTTP protocol utils." -marker = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"" -name = "httptools" -optional = false -python-versions = "*" -version = "0.1.1" - -[package.extras] -test = ["Cython (0.29.14)"] - -[[package]] -category = "main" -description = "Data validation and settings management using python 3.6 type hinting" -name = "pydantic" -optional = false -python-versions = ">=3.6" -version = "1.6.1" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] -typing_extensions = ["typing-extensions (>=3.7.2)"] - -[[package]] -category = "main" -description = "A streaming multipart parser for Python" -name = "python-multipart" -optional = false -python-versions = "*" -version = "0.0.5" - -[package.dependencies] -six = ">=1.4.0" - -[[package]] -category = "main" -description = "Python 2 and 3 compatibility utilities" -name = "six" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.15.0" - -[[package]] -category = "main" -description = "The little ASGI library that shines." -name = "starlette" -optional = false -python-versions = ">=3.6" -version = "0.12.9" - -[package.extras] -full = ["aiofiles", "graphene", "itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests", "ujson"] - -[[package]] -category = "main" -description = "The lightning-fast ASGI server." -name = "uvicorn" -optional = false -python-versions = "*" -version = "0.11.8" - -[package.dependencies] -click = ">=7.0.0,<8.0.0" -h11 = ">=0.8,<0.10" -httptools = ">=0.1.0,<0.2.0" -uvloop = ">=0.14.0" -websockets = ">=8.0.0,<9.0.0" - -[package.extras] -watchgodreload = ["watchgod (>=0.6,<0.7)"] - -[[package]] -category = "main" -description = "Fast implementation of asyncio event loop on top of libuv" -marker = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"" -name = "uvloop" -optional = false -python-versions = "*" -version = "0.14.0" - -[[package]] -category = "main" -description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -name = "websockets" -optional = false -python-versions = ">=3.6.1" -version = "8.1" - -[metadata] -content-hash = "5568a3ce063745c50d78a933959031b3186dfcad93622a98bc8fd8efcbc08edc" -lock-version = "1.0" -python-versions = "^3.7" - -[metadata.files] -aiofiles = [ - {file = "aiofiles-0.4.0-py3-none-any.whl", hash = "sha256:1e644c2573f953664368de28d2aa4c89dfd64550429d0c27c4680ccd3aa4985d"}, - {file = "aiofiles-0.4.0.tar.gz", hash = "sha256:021ea0ba314a86027c166ecc4b4c07f2d40fc0f4b3a950d1868a0f2571c2bbee"}, -] -anosql = [ - {file = "anosql-1.0.2.tar.gz", hash = "sha256:ad009427db735cd7d86e76b596a839a736a5d8531897976ec2606cbbca551ec8"}, -] -click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, -] -fastapi = [ - {file = "fastapi-0.49.2-py3-none-any.whl", hash = "sha256:e3b479c61d8a02ec6c80ebbc2ee2d621a32855ffffedd55fd5f2993c6dbdcc1e"}, - {file = "fastapi-0.49.2.tar.gz", hash = "sha256:68395725aac4342896b4f9aa335c7e7fb773b565df7f96e964e24bffb84dc5a3"}, -] -h11 = [ - {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, - {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, -] -httptools = [ - {file = "httptools-0.1.1-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:a2719e1d7a84bb131c4f1e0cb79705034b48de6ae486eb5297a139d6a3296dce"}, - {file = "httptools-0.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:fa3cd71e31436911a44620473e873a256851e1f53dee56669dae403ba41756a4"}, - {file = "httptools-0.1.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:86c6acd66765a934e8730bf0e9dfaac6fdcf2a4334212bd4a0a1c78f16475ca6"}, - {file = "httptools-0.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bc3114b9edbca5a1eb7ae7db698c669eb53eb8afbbebdde116c174925260849c"}, - {file = "httptools-0.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ac0aa11e99454b6a66989aa2d44bca41d4e0f968e395a0a8f164b401fefe359a"}, - {file = "httptools-0.1.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:96da81e1992be8ac2fd5597bf0283d832287e20cb3cfde8996d2b00356d4e17f"}, - {file = "httptools-0.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:56b6393c6ac7abe632f2294da53f30d279130a92e8ae39d8d14ee2e1b05ad1f2"}, - {file = "httptools-0.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:96eb359252aeed57ea5c7b3d79839aaa0382c9d3149f7d24dd7172b1bcecb009"}, - {file = "httptools-0.1.1-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:fea04e126014169384dee76a153d4573d90d0cbd1d12185da089f73c78390437"}, - {file = "httptools-0.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:3592e854424ec94bd17dc3e0c96a64e459ec4147e6d53c0a42d0ebcef9cb9c5d"}, - {file = "httptools-0.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:0a4b1b2012b28e68306575ad14ad5e9120b34fccd02a81eb08838d7e3bbb48be"}, - {file = "httptools-0.1.1.tar.gz", hash = "sha256:41b573cf33f64a8f8f3400d0a7faf48e1888582b6f6e02b82b9bd4f0bf7497ce"}, -] -pydantic = [ - {file = "pydantic-1.6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:418b84654b60e44c0cdd5384294b0e4bc1ebf42d6e873819424f3b78b8690614"}, - {file = "pydantic-1.6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:4900b8820b687c9a3ed753684337979574df20e6ebe4227381d04b3c3c628f99"}, - {file = "pydantic-1.6.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b49c86aecde15cde33835d5d6360e55f5e0067bb7143a8303bf03b872935c75b"}, - {file = "pydantic-1.6.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:2de562a456c4ecdc80cf1a8c3e70c666625f7d02d89a6174ecf63754c734592e"}, - {file = "pydantic-1.6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f769141ab0abfadf3305d4fcf36660e5cf568a666dd3efab7c3d4782f70946b1"}, - {file = "pydantic-1.6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2dc946b07cf24bee4737ced0ae77e2ea6bc97489ba5a035b603bd1b40ad81f7e"}, - {file = "pydantic-1.6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:36dbf6f1be212ab37b5fda07667461a9219c956181aa5570a00edfb0acdfe4a1"}, - {file = "pydantic-1.6.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:1783c1d927f9e1366e0e0609ae324039b2479a1a282a98ed6a6836c9ed02002c"}, - {file = "pydantic-1.6.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:cf3933c98cb5e808b62fae509f74f209730b180b1e3c3954ee3f7949e083a7df"}, - {file = "pydantic-1.6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f8af9b840a9074e08c0e6dc93101de84ba95df89b267bf7151d74c553d66833b"}, - {file = "pydantic-1.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:40d765fa2d31d5be8e29c1794657ad46f5ee583a565c83cea56630d3ae5878b9"}, - {file = "pydantic-1.6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3fa799f3cfff3e5f536cbd389368fc96a44bb30308f258c94ee76b73bd60531d"}, - {file = "pydantic-1.6.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:6c3f162ba175678218629f446a947e3356415b6b09122dcb364e58c442c645a7"}, - {file = "pydantic-1.6.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:eb75dc1809875d5738df14b6566ccf9fd9c0bcde4f36b72870f318f16b9f5c20"}, - {file = "pydantic-1.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:530d7222a2786a97bc59ee0e0ebbe23728f82974b1f1ad9a11cd966143410633"}, - {file = "pydantic-1.6.1-py36.py37.py38-none-any.whl", hash = "sha256:b5b3489cb303d0f41ad4a7390cf606a5f2c7a94dcba20c051cd1c653694cb14d"}, - {file = "pydantic-1.6.1.tar.gz", hash = "sha256:54122a8ed6b75fe1dd80797f8251ad2063ea348a03b77218d73ea9fe19bd4e73"}, -] -python-multipart = [ - {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"}, -] -six = [ - {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, - {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, -] -starlette = [ - {file = "starlette-0.12.9.tar.gz", hash = "sha256:c2ac9a42e0e0328ad20fe444115ac5e3760c1ee2ac1ff8cdb5ec915c4a453411"}, -] -uvicorn = [ - {file = "uvicorn-0.11.8-py3-none-any.whl", hash = "sha256:4b70ddb4c1946e39db9f3082d53e323dfd50634b95fd83625d778729ef1730ef"}, - {file = "uvicorn-0.11.8.tar.gz", hash = "sha256:46a83e371f37ea7ff29577d00015f02c942410288fb57def6440f2653fff1d26"}, -] -uvloop = [ - {file = "uvloop-0.14.0-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd"}, - {file = "uvloop-0.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726"}, - {file = "uvloop-0.14.0-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7"}, - {file = "uvloop-0.14.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"}, - {file = "uvloop-0.14.0-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891"}, - {file = "uvloop-0.14.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95"}, - {file = "uvloop-0.14.0-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5"}, - {file = "uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09"}, - {file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"}, -] -websockets = [ - {file = "websockets-8.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c"}, - {file = "websockets-8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170"}, - {file = "websockets-8.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8"}, - {file = "websockets-8.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb"}, - {file = "websockets-8.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5"}, - {file = "websockets-8.1-cp36-cp36m-win32.whl", hash = "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a"}, - {file = "websockets-8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5"}, - {file = "websockets-8.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989"}, - {file = "websockets-8.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d"}, - {file = "websockets-8.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779"}, - {file = "websockets-8.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8"}, - {file = "websockets-8.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422"}, - {file = "websockets-8.1-cp37-cp37m-win32.whl", hash = "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc"}, - {file = "websockets-8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308"}, - {file = "websockets-8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092"}, - {file = "websockets-8.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485"}, - {file = "websockets-8.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1"}, - {file = "websockets-8.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55"}, - {file = "websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824"}, - {file = "websockets-8.1-cp38-cp38-win32.whl", hash = "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36"}, - {file = "websockets-8.1-cp38-cp38-win_amd64.whl", hash = "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"}, - {file = "websockets-8.1.tar.gz", hash = "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f"}, -] diff --git a/pyproject.toml b/pyproject.toml index f3b6e5c..1789611 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,21 +1,24 @@ -[tool.poetry] +[project] name = "gpapconv" -version = "0.2.0" +version = "0.2.1" description = "Geopaparazzi to OSM XML and GeoJSON converter" -authors = ["Francesco Frassinelli "] -license = "AGPL-3.0-or-later" - -[tool.poetry.dependencies] -python = "^3.7" -aiofiles = "^0.4.0" -uvicorn = "^0.11.7" -fastapi = "^0.49.0" -python-multipart = "^0.0.5" -anosql = "^1.0.2" - -[tool.poetry.dev-dependencies] +authors = [ + {name="Francesco Frassinelli", email="fraph24@gmail.com"} +] +license = {text="AGPL-3.0-or-later"} +requires-python = ">=3.9.0" +readme = "README.md" +dependencies = [ + "aiofiles", + "uvicorn", + "fastapi", + "python-multipart", + "aiosql" +] [build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" +requires = ["setuptools>=69"] +build-backend = "setuptools.build_meta" +[tool.setuptools.package-data] +gpapconv = ["queries.sql", "index.html"] \ No newline at end of file diff --git a/src/gpapconv/__init__.py b/src/gpapconv/__init__.py new file mode 100644 index 0000000..33e7c1c --- /dev/null +++ b/src/gpapconv/__init__.py @@ -0,0 +1 @@ +from .gpapconv import app \ No newline at end of file diff --git a/gpapconv.py b/src/gpapconv/gpapconv.py similarity index 59% rename from gpapconv.py rename to src/gpapconv/gpapconv.py index 368c864..86ad36f 100644 --- a/gpapconv.py +++ b/src/gpapconv/gpapconv.py @@ -4,41 +4,50 @@ from fastapi import FastAPI, File, UploadFile from starlette.responses import FileResponse, Response -import anosql +import aiosql import datetime import json import shutil import sqlite3 import tempfile +import pathlib + +script_dir = pathlib.Path(__file__).parent.absolute() +queries = aiosql.from_path(script_dir / "queries.sql", "sqlite3") -queries = anosql.from_path('queries.sql', 'sqlite3') def run_query_on_db(db_path, query_name): with sqlite3.connect(db_path) as con: - return getattr(queries, query_name)(con)[0][0] + return getattr(queries, query_name)(con)[0] + def run_query_on_form(file, query_name): with tempfile.NamedTemporaryFile() as tf: shutil.copyfileobj(file.file, tf) return run_query_on_db(tf.name, query_name) + def generate_filename(extension): - return 'geopap-{}.{}'.format(datetime.date.today(), extension) + return "geopap-{}.{}".format(datetime.date.today(), extension) + app = FastAPI() + @app.get("/") async def index(): - return FileResponse('web/index.html') + return FileResponse(script_dir / "index.html") + @app.post("/gpap2osm") async def gpap2osm(response: Response, file: UploadFile = File(...)): - response.headers['Content-Disposition'] = generate_filename('xml') - result = run_query_on_form(file, 'gpap2osm') + response.headers["Content-Disposition"] = generate_filename("xml") + result = run_query_on_form(file, "gpap2osm") return Response(result, media_type="application/xml") + @app.post("/gpap2geojson") async def gpap2geojson(response: Response, file: UploadFile = File(...)): - response.headers['Content-Disposition'] = generate_filename('geojson') - result = run_query_on_form(file, 'gpap2geojson') + response.headers["Content-Disposition"] = generate_filename("geojson") + result = run_query_on_form(file, "gpap2geojson") return json.loads(result) diff --git a/web/index.html b/src/gpapconv/index.html similarity index 100% rename from web/index.html rename to src/gpapconv/index.html diff --git a/queries.sql b/src/gpapconv/queries.sql similarity index 97% rename from queries.sql rename to src/gpapconv/queries.sql index 486ec21..b18b3bf 100644 --- a/queries.sql +++ b/src/gpapconv/queries.sql @@ -1,4 +1,4 @@ --- name: gpap2geojson +-- name: gpap2geojson^ -- This query allows to convert notes from Geopaparazzi into a GeoJSON with osm as ( select _id, @@ -26,7 +26,7 @@ select json_object( join osm on notes._id = osm._id; --- name: gpap2osm +-- name: gpap2osm^ -- This query allows to convert notes from Geopaparazzi into a OSM XML with body as ( select '