From b8c19203407565af2ae35c86024a50b2075c5960 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Thu, 23 Oct 2025 08:27:52 +0200 Subject: [PATCH 1/3] Add jobdetails endpoint and fix field names --- .github/workflows/deutschland_generator.yaml | 40 +- .github/workflows/openapi_check.yaml | 26 +- .pre-commit-config.yaml | 59 ++ .spectral.yaml | 10 + CNAME | 2 +- README.md | 26 +- api_example.R | 2 - api_example.py | 34 +- index.html | 2 +- openapi.yaml | 883 +++++++++---------- 10 files changed, 571 insertions(+), 513 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 .spectral.yaml diff --git a/.github/workflows/deutschland_generator.yaml b/.github/workflows/deutschland_generator.yaml index b79f89e..05f7857 100644 --- a/.github/workflows/deutschland_generator.yaml +++ b/.github/workflows/deutschland_generator.yaml @@ -6,28 +6,28 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.11.1' ] + python-version: ['3.11.1'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2 # Create default .spectral.yaml file used for linting if its not existing already - - name: "Create spectral file if it not exists" - continue-on-error: true - run: | - set -C; echo "extends: spectral:oas" > .spectral.yaml + - name: "Create spectral file if it not exists" + continue-on-error: true + run: | + set -C; echo "extends: spectral:oas" > .spectral.yaml # Runs a single command using the runners shell - - name: "Lint file" - uses: stoplightio/spectral-action@v0.8.2 - with: - file_glob: "openapi.yaml" + - name: "Lint file" + uses: stoplightio/spectral-action@v0.8.2 + with: + file_glob: "openapi.yaml" - - name: "Generate deutschland code" - uses: wirthual/deutschland-generator-action@latest - with: - openapi-file: ${{ github.workspace }}/openapi.yaml - commit-to-git: true - upload-to-pypi: true - upload-to-testpypi: false - pypi-token: ${{ secrets.PYPI_PRODUCTION }} - testpypi-token: ${{ secrets.PYPI_TEST }} - python-version: ${{ matrix.python-version }} + - name: "Generate deutschland code" + uses: wirthual/deutschland-generator-action@latest + with: + openapi-file: ${{ github.workspace }}/openapi.yaml + commit-to-git: true + upload-to-pypi: true + upload-to-testpypi: false + pypi-token: ${{ secrets.PYPI_PRODUCTION }} + testpypi-token: ${{ secrets.PYPI_TEST }} + python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/openapi_check.yaml b/.github/workflows/openapi_check.yaml index c58779f..a46d71d 100644 --- a/.github/workflows/openapi_check.yaml +++ b/.github/workflows/openapi_check.yaml @@ -1,20 +1,20 @@ on: [push, pull_request] jobs: - openapi_check: - name: "OpenAPI check" - runs-on: ubuntu-latest - steps: + openapi_check: + name: "OpenAPI check" + runs-on: ubuntu-latest + steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v2 # Create default .spectral.yaml file used for linting if its not existing already - - name: "Create spectral file if it not exists" - continue-on-error: true - run: | - set -C; echo "extends: spectral:oas" > .spectral.yaml + - name: "Create spectral file if it not exists" + continue-on-error: true + run: | + set -C; echo "extends: spectral:oas" > .spectral.yaml # Run Spectral - - uses: stoplightio/spectral-action@v0.8.2 - with: - file_glob: openapi.yaml - spectral_ruleset: .spectral.yaml + - uses: stoplightio/spectral-action@v0.8.2 + with: + file_glob: openapi.yaml + spectral_ruleset: .spectral.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..13e11c9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,59 @@ +# Pre-commit hooks for jobsuche-api +# Mirrors the CI/CD pipeline checks from GitHub Actions +# Install: pre-commit install +# Run manually: pre-commit run --all-files + +# Exclude python-client/ as it's auto-generated by CI/CD +exclude: ^python-client/ + +repos: + # General file checks +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + name: Trim trailing whitespace + - id: end-of-file-fixer + name: Fix end of files + - id: check-yaml + name: Check YAML syntax + - id: check-added-large-files + name: Check for large files + args: ['--maxkb=1000'] + - id: check-merge-conflict + name: Check for merge conflicts + - id: mixed-line-ending + name: Check for mixed line endings + + # YAML formatting +- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks + rev: v2.12.0 + hooks: + - id: pretty-format-yaml + name: Format YAML files + args: + - --autofix + - --indent=2 + - --preserve-quotes + files: \.(yaml|yml)$ + + # OpenAPI/Spectral linting (mirrors GitHub Actions) +- repo: local + hooks: + - id: spectral-lint + name: Lint OpenAPI spec with Spectral + entry: npx @stoplight/spectral-cli lint + language: system + files: openapi\.yaml$ + args: + - --ruleset + - .spectral.yaml + + # Python formatting (for generated code and examples) +- repo: https://github.com/psf/black + rev: 24.2.0 + hooks: + - id: black + name: Format Python code + language_version: python3 + files: \.(py)$ diff --git a/.spectral.yaml b/.spectral.yaml new file mode 100644 index 0000000..3a576d2 --- /dev/null +++ b/.spectral.yaml @@ -0,0 +1,10 @@ +# Spectral OpenAPI linting configuration +# Used by both pre-commit hooks and GitHub Actions CI/CD +# Documentation: https://meta.stoplight.io/docs/spectral/ + +extends: spectral:oas + +# Custom rules can be added here +# rules: +# operation-operationId: warn +# operation-tags: warn diff --git a/CNAME b/CNAME index c04a5ce..bf82e7e 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -jobsuche.api.bund.dev \ No newline at end of file +jobsuche.api.bund.dev diff --git a/README.md b/README.md index 55a2e2f..3d6c59f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Arbeitsagentur Jobsuche API +# Arbeitsagentur Jobsuche API Die Bundesagentur für Arbeit verfügt über die größte Datenbank für offene Stellen in Deutschland. Obwohl sie vollständig staatlich ist und es sich dabei um einen sehr spannenden Basisdatensatz handelt, mit dem viele Analysen möglich wären, bietet die Bundesagentur für Arbeit dafür bis heute keine offizielle API an. @@ -13,7 +13,7 @@ Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu ## Jobbörse **URL:** https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobs - + Die Jobsuche ermöglicht verfügbare Jobangebote mit verschiedenen get Parametern zu filtern: @@ -62,16 +62,16 @@ Anzahl der Tage, seit der Job veröffentlicht wurde. Kann zwischen 0 und 100 Tag **Parameter:** *pav* (Optional) -- false +- false - true Private Arbeitsvermittlung: Gibt an, ob Jobs von privaten Arbeitsvermittlungen in die Suchergebnisse einbezogen werden sollen. **Parameter:** *angebotsart* (Optional) -- 1 -- 2 -- 4 +- 1 +- 2 +- 4 - 34 Angebotsart: 1=ARBEIT; 2=SELBSTAENDIGKEIT; 4=AUSBILDUNG/Duales Studium; 34=Praktikum/Trainee. @@ -85,12 +85,12 @@ Befristung: 1 = befristet; 2 = unbefristet. Mehrere Semikolon-separierte Werte m Parameter: behinderung (Optional) -- false +- false - true Parameter: corona (Optional) -- false +- false - true Corona: Es werden nur Jobs die im Kontext von Corona angeboten werden angezeigt wenn *true*. @@ -102,13 +102,13 @@ Umkreis: in Kilometern von *Wo*-Parameter (z.B. 25 oder 200). **Parameter:** *arbeitszeit* (Optional) -- vz -- tz +- vz +- tz - snw -- ho -- mj +- ho +- mj -Arbeitszeit: vz=VOLLZEIT, tz=TEILZEIT, snw=SCHICHT_NACHTARBEIT_WOCHENENDE, ho=HEIM_TELEARBEIT, mj=MINIJOB. +Arbeitszeit: vz=VOLLZEIT, tz=TEILZEIT, snw=SCHICHT_NACHTARBEIT_WOCHENENDE, ho=HEIM_TELEARBEIT, mj=MINIJOB. Mehrere Semikolon-separierte Werte möglich (z.B. arbeitszeit=vz;tz). diff --git a/api_example.R b/api_example.R index f801bc2..5b0630c 100644 --- a/api_example.R +++ b/api_example.R @@ -16,5 +16,3 @@ writeLines(jsonlite::toJSON(data$facetten,pretty=TRUE,auto_unbox=TRUE),paste0(Sy urlLogo="https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/ed/v1/arbeitgeberlogo/arJ0dxbYlPFXeMuZtdZzooRdCOnK2TjUXjLQlkBr-Ew=" dataLogo=httr::content(httr::GET(url=urlLogo, httr::add_headers(.headers=c("X-API-Key"=clientId)), config=httr::config(connecttimeout=60))) - - diff --git a/api_example.py b/api_example.py index 73d91af..3af4b97 100644 --- a/api_example.py +++ b/api_example.py @@ -1,26 +1,32 @@ import requests + def search(what, where): """search for jobs. params can be found here: https://jobsuche.api.bund.dev/""" params = ( - ('angebotsart', '1'), - ('page', '1'), - ('pav', 'false'), - ('size', '100'), - ('umkreis', '25'), - ('was', what), - ('wo', where), + ("angebotsart", "1"), + ("page", "1"), + ("pav", "false"), + ("size", "100"), + ("umkreis", "25"), + ("was", what), + ("wo", where), ) headers = { - 'User-Agent': 'Jobsuche/2.9.2 (de.arbeitsagentur.jobboerse; build:1077; iOS 15.1.0) Alamofire/5.4.4', - 'Host': 'rest.arbeitsagentur.de', - 'X-API-Key': 'jobboerse-jobsuche', - 'Connection': 'keep-alive', + "User-Agent": "Jobsuche/2.9.2 (de.arbeitsagentur.jobboerse; build:1077; iOS 15.1.0) Alamofire/5.4.4", + "Host": "rest.arbeitsagentur.de", + "X-API-Key": "jobboerse-jobsuche", + "Connection": "keep-alive", } - response = requests.get('https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/app/jobs', - headers=headers, params=params, verify=False) + response = requests.get( + "https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/app/jobs", + headers=headers, + params=params, + verify=False, + ) return response.json() + result = search("bahn", "berlin") -print(result['stellenangebote'][0]["refnr"]) +print(result["stellenangebote"][0]["refnr"]) diff --git a/index.html b/index.html index 00a052b..9e017dc 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@