diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 5f32cb8..3c2d4dc 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -3,7 +3,13 @@ name: Test tap-linkedin-ads -on: [push] +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: [main] + workflow_dispatch: + inputs: {} jobs: pytest: @@ -22,9 +28,9 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install Poetry - uses: snok/install-poetry@v1 - with: - version: 1.4.2 + run: | + pipx install poetry + poetry --version - name: Install dependencies run: | poetry install diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt new file mode 100644 index 0000000..3ca0406 --- /dev/null +++ b/.github/workflows/constraints.txt @@ -0,0 +1,5 @@ +nox==2023.4.22 +nox-poetry==1.0.2 +pip==23.1.2 +poetry==1.5.0 +poetry-dynamic-versioning==0.22.0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..41e4146 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,51 @@ +name: Publish with Dynamic Versioning + +on: + release: + types: [published] + +permissions: + contents: write + id-token: write + +jobs: + publish: + name: Publish to PyPI + runs-on: ubuntu-latest + environment: publishing + env: + PIP_CONSTRAINT: .github/workflows/constraints.txt + steps: + - name: Checkout code + uses: actions/checkout@v3.5.2 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v4.6.0 + with: + python-version: "3.10" + + - name: Upgrade pip + run: | + pip install pip + pip --version + - name: Install Poetry + run: | + pipx install poetry + pipx inject poetry poetry-dynamic-versioning[plugin] + poetry --version + poetry self show plugins + - name: Build + run: poetry build + + - name: Upload wheel to release + uses: svenstaro/upload-release-action@v2 + with: + file: dist/*.whl + tag: ${{ github.ref }} + overwrite: true + file_glob: true + + - name: Publish + uses: pypa/gh-action-pypi-publish@v1.8.6 diff --git a/README.md b/README.md index f4cc2c3..78dc40b 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,12 @@ A full list of supported settings and capabilities is available by running: `tap ### Owner -The ```owner``` setting is required for pulling data from the VideoAds endpoint. You can find the owner ID by making a +The `owner` setting is required for pulling data from the VideoAds endpoint. You can find the owner ID by making a request to the adAccounts endpoint: https://api.linkedin.com/rest/adAccounts?q=search&start=0&count=10 - The owner ID can be found in the response under "reference": "urn:li:organization:```{OWNER}```" + The owner ID can be found in the response under "reference": "urn:li:organization:`{OWNER}`" ## Installation @@ -54,9 +54,9 @@ The tap requires a LinkedInAds OAuth 2.0 access token to make API requests The access token requires the following permissions: -```r_ads```: read ads -```rw_ads```: read-write ads -```r_ads_reporting```: read ads reporting +`r_ads`: read ads +`rw_ads`: read-write ads +`r_ads_reporting`: read ads reporting Access tokens expire after 60 days and require a user to manually authenticate again. See the [LinkedInAds API docs](https://learn.microsoft.com/en-us/linkedin/shared/authentication/postman-getting-started) for more info diff --git a/poetry.lock b/poetry.lock index 467eb1c..835e8cf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand. [[package]] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = "*" files = [ @@ -16,7 +15,6 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -38,7 +36,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "backoff" version = "2.2.1" description = "Function decoration for backoff and retry" -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -50,7 +47,6 @@ files = [ name = "certifi" version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -62,7 +58,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -139,7 +134,6 @@ pycparser = "*" name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -224,7 +218,6 @@ files = [ name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -240,7 +233,6 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -252,7 +244,6 @@ files = [ name = "cryptography" version = "40.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -294,7 +285,6 @@ tox = ["tox"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -306,7 +296,6 @@ files = [ name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -321,7 +310,6 @@ test = ["pytest (>=6)"] name = "fs" version = "2.4.16" description = "Python's filesystem abstraction layer" -category = "main" optional = false python-versions = "*" files = [ @@ -341,7 +329,6 @@ scandir = ["scandir (>=1.5,<2.0)"] name = "greenlet" version = "2.0.2" description = "Lightweight in-process concurrent programming" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -415,7 +402,6 @@ test = ["objgraph", "psutil"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -427,7 +413,6 @@ files = [ name = "importlib-metadata" version = "4.13.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -448,7 +433,6 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag name = "importlib-resources" version = "5.12.0" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -467,7 +451,6 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -479,7 +462,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -491,7 +473,6 @@ files = [ name = "joblib" version = "1.2.0" description = "Lightweight pipelining with Python functions" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -503,7 +484,6 @@ files = [ name = "jsonpath-ng" version = "1.5.3" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." -category = "main" optional = false python-versions = "*" files = [ @@ -521,7 +501,6 @@ six = "*" name = "jsonschema" version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -545,7 +524,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "memoization" version = "0.4.0" description = "A powerful caching library for Python, with TTL support and multiple algorithm options. (https://github.com/lonelyenvoy/python-memoization)" -category = "main" optional = false python-versions = ">=3, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" files = [ @@ -556,7 +534,6 @@ files = [ name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -568,7 +545,6 @@ files = [ name = "pendulum" version = "2.1.2" description = "Python datetimes made easy" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -603,7 +579,6 @@ pytzdata = ">=2020.1" name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -615,7 +590,6 @@ files = [ name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -634,7 +608,6 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" -category = "main" optional = false python-versions = "*" files = [ @@ -646,7 +619,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -658,7 +630,6 @@ files = [ name = "pyjwt" version = "2.7.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -679,7 +650,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pyrsistent" version = "0.19.3" description = "Persistent/Functional/Immutable data structures" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -716,7 +686,6 @@ files = [ name = "pytest" version = "7.3.1" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -740,7 +709,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-durations" version = "1.2.0" description = "Pytest plugin reporting fixtures and test functions execution time." -category = "dev" optional = false python-versions = ">=3.6.2" files = [ @@ -755,7 +723,6 @@ pytest = ">=4.6" name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -770,7 +737,6 @@ six = ">=1.5" name = "python-dotenv" version = "0.21.1" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -785,7 +751,6 @@ cli = ["click (>=5.0)"] name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -797,7 +762,6 @@ files = [ name = "pytzdata" version = "2020.1" description = "The Olson timezone database for Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -809,7 +773,6 @@ files = [ name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -859,7 +822,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -879,26 +841,24 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "setuptools" -version = "67.7.2" +version = "67.8.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, - {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, + {file = "setuptools-67.8.0-py3-none-any.whl", hash = "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f"}, + {file = "setuptools-67.8.0.tar.gz", hash = "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "simplejson" version = "3.19.1" description = "Simple, fast, extensible JSON encoder/decoder for Python" -category = "main" optional = false python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -993,7 +953,6 @@ files = [ name = "singer-sdk" version = "0.27.0" description = "A framework for building Singer taps" -category = "main" optional = false python-versions = ">=3.7.1,<3.12" files = [ @@ -1035,7 +994,6 @@ testing = ["pytest (>=7.2.1,<8.0.0)", "pytest-durations (>=1.2.0,<2.0.0)"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1047,7 +1005,6 @@ files = [ name = "sqlalchemy" version = "1.4.48" description = "Database Abstraction Library" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -1095,7 +1052,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\")"} importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [package.extras] @@ -1123,7 +1080,6 @@ sqlcipher = ["sqlcipher3-binary"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1133,26 +1089,24 @@ files = [ [[package]] name = "typing-extensions" -version = "4.5.0" +version = "4.6.2" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, + {file = "typing_extensions-4.6.2-py3-none-any.whl", hash = "sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98"}, + {file = "typing_extensions-4.6.2.tar.gz", hash = "sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c"}, ] [[package]] name = "urllib3" -version = "1.26.15" +version = "1.26.16" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, - {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, + {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, ] [package.extras] @@ -1164,7 +1118,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "zipp" version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1178,5 +1131,5 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" -python-versions = "<3.11,>=3.7.1" -content-hash = "c0cfac4449b97335c37826e85a1c923a4844feb9d6de7b1fc8eeeec418d9769c" +python-versions = "<3.12,>=3.7.1" +content-hash = "9d31781b42d48efe6b8da16b4fefaca31b5c24ad48772b302facd2ae840f4247" diff --git a/pyproject.toml b/pyproject.toml index a530e91..51e851d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,20 @@ [tool.poetry] -name = "tap-linkedin-ads" -version = "0.0.1" +name = "meltano-tap-linkedin-ads" +version = "0.0.0" description = "`tap-linkedin-ads` is a Singer tap for linkedin, built with the Meltano SDK for Singer Taps." -authors = ["Meltano"] +authors = ["Meltano "] keywords = [ "ELT", "linkedin", ] -license = "Apache 2.0" +license = "Elastic-2.0" +packages = [ + { include = "tap_linkedin_ads" }, +] +readme = "README.md" [tool.poetry.dependencies] -python = "<3.11,>=3.7.1" +python = "<3.12,>=3.7.1" pendulum = "^2.1.2" requests = "^2.31.0" singer-sdk = "^0.27.0" @@ -25,13 +29,16 @@ multi_line_output = 3 # Vertical Hanging Indent src_paths = "tap_linkedin_ads" [build-system] -requires = ["poetry-core>=1.0.8"] -build-backend = "poetry.core.masonry.api" +requires = ["poetry-core==1.6.1", "poetry-dynamic-versioning"] +build-backend = "poetry_dynamic_versioning.backend" [tool.poetry.scripts] # CLI declaration tap-linkedin-ads = 'tap_linkedin_ads.tap:TapLinkedInAds.cli' +[tool.poetry-dynamic-versioning] +enable = true + [tool.ruff] ignore = [ "ANN101", # Missing type annotation for self in method