tr-acikveri 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tr_acikveri-0.1.0/CHANGELOG.md +27 -0
- tr_acikveri-0.1.0/CITATION.cff +21 -0
- tr_acikveri-0.1.0/LICENSE +21 -0
- tr_acikveri-0.1.0/MANIFEST.in +9 -0
- tr_acikveri-0.1.0/PKG-INFO +313 -0
- tr_acikveri-0.1.0/README.md +267 -0
- tr_acikveri-0.1.0/examples/quickstart.py +38 -0
- tr_acikveri-0.1.0/pyproject.toml +126 -0
- tr_acikveri-0.1.0/setup.cfg +4 -0
- tr_acikveri-0.1.0/src/tr_acikveri/__init__.py +99 -0
- tr_acikveri-0.1.0/src/tr_acikveri/__main__.py +7 -0
- tr_acikveri-0.1.0/src/tr_acikveri/_version.py +1 -0
- tr_acikveri-0.1.0/src/tr_acikveri/cache.py +119 -0
- tr_acikveri-0.1.0/src/tr_acikveri/ckan.py +268 -0
- tr_acikveri-0.1.0/src/tr_acikveri/cli.py +366 -0
- tr_acikveri-0.1.0/src/tr_acikveri/client.py +309 -0
- tr_acikveri-0.1.0/src/tr_acikveri/errors.py +54 -0
- tr_acikveri-0.1.0/src/tr_acikveri/http.py +374 -0
- tr_acikveri-0.1.0/src/tr_acikveri/models.py +308 -0
- tr_acikveri-0.1.0/src/tr_acikveri/portals.py +391 -0
- tr_acikveri-0.1.0/src/tr_acikveri/py.typed +0 -0
- tr_acikveri-0.1.0/src/tr_acikveri/readers.py +362 -0
- tr_acikveri-0.1.0/src/tr_acikveri.egg-info/PKG-INFO +313 -0
- tr_acikveri-0.1.0/src/tr_acikveri.egg-info/SOURCES.txt +35 -0
- tr_acikveri-0.1.0/src/tr_acikveri.egg-info/dependency_links.txt +1 -0
- tr_acikveri-0.1.0/src/tr_acikveri.egg-info/entry_points.txt +2 -0
- tr_acikveri-0.1.0/src/tr_acikveri.egg-info/requires.txt +19 -0
- tr_acikveri-0.1.0/src/tr_acikveri.egg-info/top_level.txt +1 -0
- tr_acikveri-0.1.0/tests/conftest.py +70 -0
- tr_acikveri-0.1.0/tests/mockserver.py +423 -0
- tr_acikveri-0.1.0/tests/test_ckan.py +175 -0
- tr_acikveri-0.1.0/tests/test_cli.py +193 -0
- tr_acikveri-0.1.0/tests/test_client.py +147 -0
- tr_acikveri-0.1.0/tests/test_http.py +199 -0
- tr_acikveri-0.1.0/tests/test_models.py +103 -0
- tr_acikveri-0.1.0/tests/test_portals.py +115 -0
- tr_acikveri-0.1.0/tests/test_readers.py +242 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-11-09
|
|
8
|
+
### Added
|
|
9
|
+
- Portal registry (`list_portals`, `get_portal`, `register_portal`) with 13 CKAN
|
|
10
|
+
portals verified on 2026-11-09 (İBB, İzmir, Konya, Gaziantep, Balıkesir, Denizli,
|
|
11
|
+
Trabzon, Manisa, Çanakkale, Bursa Açık Yeşil, Kadıköy, Tuzla, Nilüfer) and
|
|
12
|
+
non-CKAN / unreachable portals listed as unsupported; licence notes per portal;
|
|
13
|
+
lookup by key, alias, city name (Turkish letters folded) or any CKAN URL.
|
|
14
|
+
- `CkanClient` for the CKAN Action API v3 (GET only): `package_search` with format,
|
|
15
|
+
organization and tag filters, paging iterator, `package_show`, `resource_show`,
|
|
16
|
+
`organization_list`, `tag_list`, `license_list`, `datastore_search`.
|
|
17
|
+
- `AcikVeri` multi-portal client: parallel search across portals with per-portal
|
|
18
|
+
error reporting, resource listing filtered by normalised format (CSV, GeoJSON,
|
|
19
|
+
SHP, XLSX ...), downloads into an on-disk cache with provenance sidecar.
|
|
20
|
+
- Polite HTTP: `tr-acikveri/<version>` User-Agent with optional contact, per-host rate
|
|
21
|
+
limit, timeouts, retries with exponential backoff and `Retry-After`, resumable
|
|
22
|
+
downloads via HTTP `Range`, size limit, certifi-aware TLS context.
|
|
23
|
+
- Readers: encoding detection (UTF-8 BOM, UTF-8, cp1254, ISO-8859-9), delimiter
|
|
24
|
+
sniffing (`;` first), Turkish number parsing, GeoJSON with legacy `crs` member;
|
|
25
|
+
optional pandas / openpyxl / geopandas helpers.
|
|
26
|
+
- Turkish CLI `tr-acikveri` with `portallar`, `ara`, `bilgi`, `indir`, `kurumlar`,
|
|
27
|
+
`etiketler`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
authors:
|
|
4
|
+
- family-names: "Eminoğlu"
|
|
5
|
+
given-names: "Yusuf"
|
|
6
|
+
email: "geospacephilo@gmail.com"
|
|
7
|
+
orcid: "https://orcid.org/0009-0005-6000-2934"
|
|
8
|
+
title: "tr-acikveri"
|
|
9
|
+
version: "0.1.0"
|
|
10
|
+
date-released: "2026-11-09"
|
|
11
|
+
license: "MIT"
|
|
12
|
+
repository-code: "https://github.com/YusufEminoglu/tr_acikveri_sdk"
|
|
13
|
+
url: "https://pypi.org/project/tr-acikveri/"
|
|
14
|
+
abstract: "One Python client for Turkish public open-data portals running CKAN (İBB, İzmir, Konya, Gaziantep and others): multi-portal dataset search, metadata and resource listing by format, polite cached and resumable downloads, and readers for cp1254 / UTF-8 BOM, semicolon-delimited CSV and GeoJSON, with a Turkish command-line interface."
|
|
15
|
+
keywords:
|
|
16
|
+
- open data
|
|
17
|
+
- açık veri
|
|
18
|
+
- CKAN
|
|
19
|
+
- Türkiye
|
|
20
|
+
- municipality
|
|
21
|
+
- GIS
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yusuf Eminoğlu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tr-acikveri
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Türkiye açık veri portalları (CKAN) için tek istemci: çoklu portal arama, veri seti bilgisi, kibar ve sürdürülebilir indirme, cp1254/UTF-8 BOM ve ; ayraçlı CSV ile GeoJSON okuma, Türkçe CLI.
|
|
5
|
+
Author-email: Yusuf Eminoğlu <geospacephilo@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/YusufEminoglu/tr_acikveri_sdk
|
|
8
|
+
Project-URL: Repository, https://github.com/YusufEminoglu/tr_acikveri_sdk
|
|
9
|
+
Project-URL: Issues, https://github.com/YusufEminoglu/tr_acikveri_sdk/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/YusufEminoglu/tr_acikveri_sdk/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: open-data,acik-veri,ckan,turkey,turkiye,istanbul,izmir,municipality,csv,geojson,gis,urban-planning
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Environment :: Console
|
|
21
|
+
Classifier: Natural Language :: Turkish
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
24
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
25
|
+
Classifier: Intended Audience :: Science/Research
|
|
26
|
+
Classifier: Intended Audience :: Developers
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Provides-Extra: pandas
|
|
32
|
+
Requires-Dist: pandas>=1.3.0; extra == "pandas"
|
|
33
|
+
Provides-Extra: excel
|
|
34
|
+
Requires-Dist: pandas>=1.3.0; extra == "excel"
|
|
35
|
+
Requires-Dist: openpyxl>=3.0.0; extra == "excel"
|
|
36
|
+
Provides-Extra: geo
|
|
37
|
+
Requires-Dist: geopandas>=0.10.0; extra == "geo"
|
|
38
|
+
Provides-Extra: certifi
|
|
39
|
+
Requires-Dist: certifi; extra == "certifi"
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
43
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
44
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
45
|
+
Dynamic: license-file
|
|
46
|
+
|
|
47
|
+
# tr-acikveri
|
|
48
|
+
|
|
49
|
+
[](https://pypi.org/project/tr-acikveri/)
|
|
50
|
+
[](https://pypi.org/project/tr-acikveri/)
|
|
51
|
+
[](https://github.com/YusufEminoglu/tr_acikveri_sdk/actions/workflows/ci.yml)
|
|
52
|
+
[](LICENSE)
|
|
53
|
+
|
|
54
|
+
**English summary.** `tr-acikveri` is one Python client for Turkish public open-data
|
|
55
|
+
portals that run CKAN (Istanbul İBB, İzmir, Konya, Gaziantep, Manisa, Trabzon and
|
|
56
|
+
others): search datasets across many portals, inspect metadata, list resources by
|
|
57
|
+
format, and download them politely with caching, rate limiting, retries and resume.
|
|
58
|
+
It reads the CSV files these portals actually publish (Windows-1254 or UTF-8 with BOM,
|
|
59
|
+
`;` delimiters, decimal commas) and GeoJSON, ships a Turkish CLI, and reminds you that
|
|
60
|
+
every dataset's licence belongs to the publishing portal.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
**Türkiye'deki açık veri portalları için tek istemci.**
|
|
65
|
+
|
|
66
|
+
Belediyelerin ve kurumların açık veri portallarının çoğu
|
|
67
|
+
[CKAN](https://ckan.org) üzerinde çalışır ve aynı *CKAN Action API*'sini sunar.
|
|
68
|
+
`tr-acikveri` bu portalları tek bir arayüzün arkasına koyar:
|
|
69
|
+
|
|
70
|
+
- Bir veya birden çok portalda **veri seti arama** (portallar paralel sorgulanır,
|
|
71
|
+
hata veren portal aramayı durdurmaz).
|
|
72
|
+
- **Kurum, etiket, veri seti bilgisi** ve **biçime göre kaynak listeleme**
|
|
73
|
+
(CSV, GeoJSON, SHP, XLSX, KML ...; portalların tutarsız biçim adları normalleştirilir).
|
|
74
|
+
- **Kibar indirme:** `tr-acikveri/<sürüm>` User-Agent'ı, sunucu başına hız sınırı,
|
|
75
|
+
zaman aşımı, `Retry-After` dikkate alan yeniden deneme, diskte önbellek ve
|
|
76
|
+
yarıda kalan indirmeyi **kaldığı yerden sürdürme** (HTTP `Range`).
|
|
77
|
+
- **Türkçe dosyalar:** cp1254 / UTF-8 BOM kodlama tespiti, `;` ayraç tespiti,
|
|
78
|
+
`1.234,56` gibi sayıların okunması, eski `crs` alanlı GeoJSON (ör. EPSG:5254).
|
|
79
|
+
- İsteğe bağlı **pandas / geopandas** dönüşümleri ve Türkçe **komut satırı** (`ara`,
|
|
80
|
+
`bilgi`, `indir`, `portallar`, `kurumlar`, `etiketler`).
|
|
81
|
+
|
|
82
|
+
Yalnızca Python standart kütüphanesiyle çalışır; Python 3.9 ve üstü gerekir.
|
|
83
|
+
|
|
84
|
+
> **Lisans uyarısı.** Bu paket MIT lisanslıdır, ancak **indirdiğiniz verilerin lisansı
|
|
85
|
+
> her portala ve veriyi yayımlayan kuruma aittir** (İBB Açık Veri Lisansı, İzmir BB Açık
|
|
86
|
+
> Veri Lisansı, CC BY 4.0, CC BY-NC ...). Paket size veriler üzerinde hiçbir hak
|
|
87
|
+
> vermez. Her veri setinin lisansını (`bilgi` komutu veya `Dataset.license_title`)
|
|
88
|
+
> okuyun, koşullarına uyun ve kaynak gösterin. Ticari olmayan (NC) lisanslara özellikle
|
|
89
|
+
> dikkat edin.
|
|
90
|
+
|
|
91
|
+
## Kurulum
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pip install tr-acikveri # yalnızca standart kütüphane
|
|
95
|
+
pip install "tr-acikveri[pandas]" # + DataFrame dönüşümü
|
|
96
|
+
pip install "tr-acikveri[excel]" # + XLSX/XLS okuma (pandas + openpyxl)
|
|
97
|
+
pip install "tr-acikveri[geo]" # + GeoDataFrame (geopandas)
|
|
98
|
+
pip install "tr-acikveri[certifi]" # + Mozilla CA paketi (bkz. "TLS sertifikaları")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Hızlı başlangıç (komut satırı)
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
tr-acikveri portallar # CKAN portalları
|
|
105
|
+
tr-acikveri portallar --hepsi # CKAN olmayanlar dahil
|
|
106
|
+
tr-acikveri ara otopark -p ibb -p izmir -f csv -n 5
|
|
107
|
+
tr-acikveri bilgi ibb ispark-otopark-bilgileri
|
|
108
|
+
tr-acikveri indir konya otopark-bilgileri -f csv -o veri/
|
|
109
|
+
tr-acikveri kurumlar izmir --json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Örnek çıktı (kısaltılmış, 2026-11-09):
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
[konya] otopark-bilgileri
|
|
116
|
+
Otopark Bilgileri (CSV) · Destek Hizmetleri Dairesi Başkanlığı
|
|
117
|
+
[izmir] otopark-ucretleri
|
|
118
|
+
Otopark Ücretleri (CSV, XLSX) · İZELMAN A.Ş.
|
|
119
|
+
|
|
120
|
+
Toplam eşleşme 3 (izmir: 2; konya: 1); gösterilen 3.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Ortak seçenekler: `--onbellek KLASÖR`, `--onbellek-suresi SN`, `--onbelleksiz`,
|
|
124
|
+
`--zaman-asimi SN`, `--aralik SN` (aynı sunucuya iki istek arası, varsayılan 1 sn),
|
|
125
|
+
`--yeniden-deneme N`, `--iletisim E-POSTA` (User-Agent'a eklenir), `--json`.
|
|
126
|
+
`-p` portal anahtarı, şehir adı (`İzmir`, `istanbul`) veya herhangi bir CKAN adresi
|
|
127
|
+
olabilir. Yönlendirilen çıktı (ör. `> sonuc.json`) her zaman UTF-8 yazılır.
|
|
128
|
+
|
|
129
|
+
## Hızlı başlangıç (Python)
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from tr_acikveri import AcikVeri
|
|
133
|
+
|
|
134
|
+
av = AcikVeri(contact="ad.soyad@kurum.edu.tr") # iletişim adresi önerilir
|
|
135
|
+
|
|
136
|
+
sonuc = av.search("otopark", portals=["ibb", "izmir", "konya"], formats=["csv"], rows=5)
|
|
137
|
+
for ds in sonuc:
|
|
138
|
+
print(ds.portal, ds.name, ds.formats, ds.license_title)
|
|
139
|
+
print(sonuc.counts, sonuc.errors)
|
|
140
|
+
|
|
141
|
+
ds = av.dataset("konya", "otopark-bilgileri")
|
|
142
|
+
kaynak = ds.resources_by_format(["csv"])[0]
|
|
143
|
+
tablo = av.read_csv(kaynak) # indirir (önbellek) ve okur
|
|
144
|
+
print(tablo.encoding, tablo.delimiter, tablo.columns)
|
|
145
|
+
kapasite = tablo.numeric("bolgekapasite") # "1.250" -> 1250.0
|
|
146
|
+
|
|
147
|
+
df = av.to_dataframe(kaynak, numeric=True) # [pandas]
|
|
148
|
+
|
|
149
|
+
parklar = av.search("park", portals=["trabzon"], formats=["geojson"]).datasets[0]
|
|
150
|
+
geo_kaynak = parklar.resources_by_format(["geojson"])[0]
|
|
151
|
+
geo = av.read_geojson(geo_kaynak) # FeatureCollection dict
|
|
152
|
+
gdf = av.to_geodataframe(geo_kaynak) # [geo]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Tek portal için alt düzey istemci:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from tr_acikveri import CkanClient
|
|
159
|
+
|
|
160
|
+
ibb = CkanClient("ibb")
|
|
161
|
+
sayi, sayfa = ibb.search("bisiklet", formats=["geojson"], sort="metadata_modified desc")
|
|
162
|
+
for ds in ibb.iter_search("hava kalitesi", limit=200):
|
|
163
|
+
...
|
|
164
|
+
kayitlar = ibb.datastore_search(resource_id, limit=100, filters={"ilce": "Kadıköy"})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Portal kaydı
|
|
168
|
+
|
|
169
|
+
Her kayıt 2026-11-09 tarihinde `<adres>/api/3/action/status_show` adresine yapılan tek
|
|
170
|
+
bir salt okunur `GET` isteğiyle doğrulandı; lisans notları portalın `license_list`
|
|
171
|
+
ve `package_search` yanıtlarından alındı. Veri seti sayıları aynı tarihe aittir.
|
|
172
|
+
|
|
173
|
+
| Anahtar | Portal | Adres | Veri seti | Lisans (portalın bildirdiği) |
|
|
174
|
+
|---|---|---|---:|---|
|
|
175
|
+
| `ibb` | İstanbul BB | https://data.ibb.gov.tr | 565 | İBB Açık Veri Lisansı |
|
|
176
|
+
| `izmir` | İzmir BB | https://acikveri.bizizmir.com | 251 | İzmir BB Açık Veri Lisansı; bazıları CC BY / belirtilmemiş |
|
|
177
|
+
| `konya` | Konya BB | https://acikveri.konya.bel.tr | 233 | CC BY 4.0 |
|
|
178
|
+
| `gaziantep` | Gaziantep | https://acikveri.gaziantep.bel.tr | 252 | Gaziantep Açık Veri Lisansı |
|
|
179
|
+
| `balikesir` | Balıkesir BB | https://acikveri.balikesir.bel.tr | 252 | Balıkesir Açık Veri Lisansı |
|
|
180
|
+
| `denizli` | Denizli | https://acikveri.denizli.bel.tr | 39 | Denizli Açık Veri Lisansı |
|
|
181
|
+
| `trabzon` | Trabzon BB | https://acikveri.trabzon.bel.tr | 206 | Trabzon Açık Veri Lisansı |
|
|
182
|
+
| `manisa` | Manisa BB | https://acikveri.manisa.bel.tr | 1389 | Manisa BB Açık Veri Lisansı (mbb-odl-1.0) |
|
|
183
|
+
| `canakkale` | Çanakkale | https://acikveri.canakkale.bel.tr | 123 | Çanakkale Açık Veri Lisansı |
|
|
184
|
+
| `bursa-yesil` | Bursa Açık Yeşil | https://acikyesil.bursa.bel.tr | 49 | kurum lisansı (yalnızca yeşil alan verisi) |
|
|
185
|
+
| `kadikoy` | Kadıköy (ilçe) | https://acikveri.kadikoy.bel.tr | 161 | karışık: CC BY, CC BY-NC, CC BY-ND |
|
|
186
|
+
| `tuzla` | Tuzla (ilçe) | https://veri.tuzla.bel.tr | 91 | CC BY |
|
|
187
|
+
| `nilufer` | Nilüfer (ilçe) | https://acikveri.nilufer.bel.tr | 65 | çoğunda belirtilmemiş; bazıları CC BY / CC BY-NC |
|
|
188
|
+
|
|
189
|
+
Desteklenmeyen (CKAN API'si yok veya kontrol sırasında erişilemedi) ve
|
|
190
|
+
`portallar --hepsi` ile listelenenler: Ankara (seffaf.ankara.bel.tr), Kocaeli
|
|
191
|
+
(veri.kocaeli.bel.tr), Kayseri, Küçükçekmece, Sağlık Bakanlığı (özel yazılım);
|
|
192
|
+
Antalya, Sakarya ve ULASAV (ulasav.csb.gov.tr; erişilemedi, API türü doğrulanamadı).
|
|
193
|
+
Gaziantep, Denizli, Trabzon, Çanakkale, Balıkesir ve Bursa Açık Yeşil portalları
|
|
194
|
+
`ulasav-license` kimlikli ortak CKAN şablonunu kullanır; lisans metni her portalın
|
|
195
|
+
`/license` sayfasındadır.
|
|
196
|
+
|
|
197
|
+
Kayıtta olmayan bir CKAN portalı adresle kullanılabilir veya kaydedilebilir:
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from tr_acikveri import Portal, register_portal, CkanClient
|
|
201
|
+
|
|
202
|
+
CkanClient("https://acikveri.ornek.bel.tr").search("imar")
|
|
203
|
+
register_portal(Portal("ornek", "Örnek Belediyesi", "https://acikveri.ornek.bel.tr",
|
|
204
|
+
city="Örnek", license_note="CC BY 4.0"))
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Portallar değişir: adres taşınabilir, API kapanabilir. Kayıttaki bilgiler kontrol
|
|
208
|
+
tarihindeki durumu yansıtır.
|
|
209
|
+
|
|
210
|
+
## API özeti
|
|
211
|
+
|
|
212
|
+
| Nesne | Açıklama |
|
|
213
|
+
|---|---|
|
|
214
|
+
| `AcikVeri(portals=None, cache_dir=None, cache_ttl=86400, contact=None, timeout=30, min_interval=1.0, retries=3, max_workers=4)` | Çok portallı istemci |
|
|
215
|
+
| `.search(query, portals, formats, rows, organization, tags, sort)` → `SearchResult` | `datasets`, `counts`, `errors`, `total` |
|
|
216
|
+
| `.dataset(portal, ad)` → `Dataset`; `.resources(portal, ad, formats)` → `[Resource]` | Meta veri ve kaynaklar |
|
|
217
|
+
| `.organizations(portal)`, `.tags(portal, query)` | Kurumlar, etiketler |
|
|
218
|
+
| `.download(resource, dest=None, overwrite, resume, max_bytes, progress)` → `Path` | Önbelleğe veya hedefe indirme; `.meta.json` kaynak bilgisi |
|
|
219
|
+
| `.download_dataset(portal, ad, formats, dest_dir)` | Veri setinin tüm dosyaları |
|
|
220
|
+
| `.read_csv`, `.read_geojson`, `.load`, `.to_dataframe`, `.to_geodataframe` | Okuma |
|
|
221
|
+
| `CkanClient(portal)` | `search`, `iter_search`, `dataset`, `resource`, `organizations`, `tags`, `licenses`, `datastore_search`, `action` |
|
|
222
|
+
| `list_portals`, `get_portal`, `register_portal`, `Portal` | Portal kaydı |
|
|
223
|
+
| `read_csv`, `CsvTable`, `detect_encoding`, `sniff_delimiter`, `parse_number`, `read_geojson`, `geojson_crs` | Dosya okuyucular |
|
|
224
|
+
| `HttpClient`, `RetryPolicy`, `RateLimiter`, `Cache` | Taşıma katmanı |
|
|
225
|
+
| `AcikVeriError` → `HttpError`, `TransportError`, `CkanError` → `NotFoundError`, `UnsupportedPortalError`, `PortalNotFoundError`, `FormatError`, `MissingDependencyError` | Hatalar |
|
|
226
|
+
|
|
227
|
+
## Yöntem ve kaynaklar
|
|
228
|
+
|
|
229
|
+
- **CKAN Action API v3** — yalnızca okuma eylemleri (`status_show`, `package_search`,
|
|
230
|
+
`package_show`, `resource_show`, `organization_list`, `tag_list`, `license_list`,
|
|
231
|
+
`datastore_search`), hepsi `GET` ile. Kaynak: CKAN API belgeleri,
|
|
232
|
+
https://docs.ckan.org/en/2.9/api/. `package_search` için `rows` en fazla 1000'e
|
|
233
|
+
sınırlanır (CKAN'ın `ckan.search.rows_max` varsayılanı).
|
|
234
|
+
- **Biçim filtresi** — `res_format` Solr'da birebir eşleşen bir alan olduğundan,
|
|
235
|
+
portallarda görülen yazımların tamamı (`CSV`, `csv`, `.csv`, `GeoJSON`, `.shp`,
|
|
236
|
+
`Excel` ...) sunucuya gönderilir; sonuç ayrıca istemci tarafında normalleştirilmiş
|
|
237
|
+
biçimle süzülür.
|
|
238
|
+
- **HTTP** — `Retry-After` (saniye veya HTTP tarihi) ve `Range`/`Content-Range`
|
|
239
|
+
ile sürdürme: RFC 9110 §10.2.3 ve §14. Yeniden deneme 408/425/429/5xx ve ağ
|
|
240
|
+
hatalarında, üstel bekleme (+%10 rastgele) ile yapılır. Hız sınırı sunucu (host)
|
|
241
|
+
başınadır ve iş parçacıkları arasında paylaşılır.
|
|
242
|
+
- **Kodlama** — sıra: UTF-8 BOM → UTF-16 BOM → katı UTF-8 → Windows-1254 (cp1254,
|
|
243
|
+
Türkçe Windows kod sayfası) → ISO-8859-9. Ayraç, ilk 50 satırda en tutarlı sütun
|
|
244
|
+
sayısını veren adaydır (`;`, `,`, sekme, `|`; eşitlikte `;`).
|
|
245
|
+
- **Sayılar** — `parse_number` Türkçe yazımı (ondalık virgül, binlik nokta) varsayar;
|
|
246
|
+
yalnızca nokta içeren ve binlik gruplamaya uymayan değerler (`12.5`) ondalık
|
|
247
|
+
okunur. `%`, `TL`, `₺` ve boşluklar yok sayılır.
|
|
248
|
+
- **GeoJSON** — RFC 7946 (WGS 84, `EPSG:4326`). 2008 GeoJSON belirtimindeki `crs`
|
|
249
|
+
alanı varsa (`urn:ogc:def:crs:EPSG::5254` gibi) `geojson_crs` bu kodu döndürür ve
|
|
250
|
+
`to_geodataframe` onu kullanır.
|
|
251
|
+
|
|
252
|
+
## TLS sertifikaları
|
|
253
|
+
|
|
254
|
+
Sertifika doğrulaması her zaman açıktır. Bazı portallar (kontrol tarihinde
|
|
255
|
+
`data.ibb.gov.tr`) Windows'un yalnızca gerektiğinde indirdiği bir kök sertifikaya
|
|
256
|
+
zincirlenir; Python bu durumda `CERTIFICATE_VERIFY_FAILED` hatası verir.
|
|
257
|
+
`certifi` kuruluysa (`pip install "tr-acikveri[certifi]"`) paket otomatik olarak
|
|
258
|
+
Mozilla CA paketini kullanır. Alternatifler: `SSL_CERT_FILE` ortam değişkeni,
|
|
259
|
+
`HttpClient(ca_file=...)` veya `HttpClient(ssl_context=...)`.
|
|
260
|
+
|
|
261
|
+
## Önbellek
|
|
262
|
+
|
|
263
|
+
Varsayılan klasör `TR_ACIKVERI_CACHE` ortam değişkeni, yoksa Windows'ta
|
|
264
|
+
`%LOCALAPPDATA%\tr-acikveri`, diğer sistemlerde `~/.cache/tr-acikveri`'dir.
|
|
265
|
+
API yanıtları `api/` altında (varsayılan 1 gün), indirilen dosyalar
|
|
266
|
+
`files/<portal>/<kaynak kimliği>/` altında tutulur. Her dosyanın yanında kaynak
|
|
267
|
+
adresi, portal, veri seti, indirme zamanı ve HTTP doğrulayıcılarını içeren bir
|
|
268
|
+
`.meta.json` bulunur. İndirilen verileri bir git deposuna eklemeyin.
|
|
269
|
+
|
|
270
|
+
## Sınırlamalar
|
|
271
|
+
|
|
272
|
+
- Yalnızca CKAN portalları desteklenir; özel yazılımlı portallar (Ankara, Kocaeli,
|
|
273
|
+
Kayseri, Sağlık Bakanlığı ...) kayıtta yalnızca bilgi amaçlıdır.
|
|
274
|
+
- Portal listesi, veri seti sayıları ve lisans notları 2026-11-09 tarihli kontrollere
|
|
275
|
+
dayanır; değişebilir. Bağlayıcı olan, veri setinin portaldaki lisansıdır.
|
|
276
|
+
- Kodlama tespiti sezgiseldir: UTF-8 olarak geçerli olan cp1254 dosyaları (çok nadir)
|
|
277
|
+
UTF-8 sayılır; gerekirse `encoding="cp1254"` verin.
|
|
278
|
+
- `API`/`HTML` türündeki kaynaklar dosya değildir ve varsayılan olarak indirilmez.
|
|
279
|
+
- Çok portallı aramada `rows` portal başına uygulanır; sonuçlar portallar arasında
|
|
280
|
+
yeniden sıralanmaz.
|
|
281
|
+
- Önbellekteki dosya, sunucuda güncellense bile `overwrite=True` (CLI: `--yeniden`)
|
|
282
|
+
verilmedikçe yeniden indirilmez.
|
|
283
|
+
|
|
284
|
+
## Geliştirme
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
pip install -e ".[dev,pandas]"
|
|
288
|
+
pytest --cov=tr_acikveri
|
|
289
|
+
ruff check . && ruff format --check src tests && mypy src
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Testler gerçek ağa hiç çıkmaz: `tests/mockserver.py` iki CKAN portalını, hatalı
|
|
293
|
+
portalları (500, HTML), 429/503 yanıtlarını, bağlantısı yarıda kopan indirmeleri ve
|
|
294
|
+
`Range` desteği olmayan sunucuları taklit eden yerel bir HTTP sunucusudur.
|
|
295
|
+
|
|
296
|
+
## Lisans
|
|
297
|
+
|
|
298
|
+
MIT © 2026 Yusuf Eminoğlu. Bkz. [LICENSE](LICENSE). Bu lisans yalnızca yazılımı
|
|
299
|
+
kapsar; portallardan alınan veriler kendi lisanslarına tabidir.
|
|
300
|
+
|
|
301
|
+
## Academic citation
|
|
302
|
+
|
|
303
|
+
```bibtex
|
|
304
|
+
@software{eminoglu_tr_acikveri,
|
|
305
|
+
author = {Eminoğlu, Yusuf},
|
|
306
|
+
title = {tr-acikveri},
|
|
307
|
+
year = {2026},
|
|
308
|
+
version = {0.1.0},
|
|
309
|
+
url = {https://github.com/YusufEminoglu/tr_acikveri_sdk}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Ayrıca bkz. `CITATION.cff`.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# tr-acikveri
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/tr-acikveri/)
|
|
4
|
+
[](https://pypi.org/project/tr-acikveri/)
|
|
5
|
+
[](https://github.com/YusufEminoglu/tr_acikveri_sdk/actions/workflows/ci.yml)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
**English summary.** `tr-acikveri` is one Python client for Turkish public open-data
|
|
9
|
+
portals that run CKAN (Istanbul İBB, İzmir, Konya, Gaziantep, Manisa, Trabzon and
|
|
10
|
+
others): search datasets across many portals, inspect metadata, list resources by
|
|
11
|
+
format, and download them politely with caching, rate limiting, retries and resume.
|
|
12
|
+
It reads the CSV files these portals actually publish (Windows-1254 or UTF-8 with BOM,
|
|
13
|
+
`;` delimiters, decimal commas) and GeoJSON, ships a Turkish CLI, and reminds you that
|
|
14
|
+
every dataset's licence belongs to the publishing portal.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
**Türkiye'deki açık veri portalları için tek istemci.**
|
|
19
|
+
|
|
20
|
+
Belediyelerin ve kurumların açık veri portallarının çoğu
|
|
21
|
+
[CKAN](https://ckan.org) üzerinde çalışır ve aynı *CKAN Action API*'sini sunar.
|
|
22
|
+
`tr-acikveri` bu portalları tek bir arayüzün arkasına koyar:
|
|
23
|
+
|
|
24
|
+
- Bir veya birden çok portalda **veri seti arama** (portallar paralel sorgulanır,
|
|
25
|
+
hata veren portal aramayı durdurmaz).
|
|
26
|
+
- **Kurum, etiket, veri seti bilgisi** ve **biçime göre kaynak listeleme**
|
|
27
|
+
(CSV, GeoJSON, SHP, XLSX, KML ...; portalların tutarsız biçim adları normalleştirilir).
|
|
28
|
+
- **Kibar indirme:** `tr-acikveri/<sürüm>` User-Agent'ı, sunucu başına hız sınırı,
|
|
29
|
+
zaman aşımı, `Retry-After` dikkate alan yeniden deneme, diskte önbellek ve
|
|
30
|
+
yarıda kalan indirmeyi **kaldığı yerden sürdürme** (HTTP `Range`).
|
|
31
|
+
- **Türkçe dosyalar:** cp1254 / UTF-8 BOM kodlama tespiti, `;` ayraç tespiti,
|
|
32
|
+
`1.234,56` gibi sayıların okunması, eski `crs` alanlı GeoJSON (ör. EPSG:5254).
|
|
33
|
+
- İsteğe bağlı **pandas / geopandas** dönüşümleri ve Türkçe **komut satırı** (`ara`,
|
|
34
|
+
`bilgi`, `indir`, `portallar`, `kurumlar`, `etiketler`).
|
|
35
|
+
|
|
36
|
+
Yalnızca Python standart kütüphanesiyle çalışır; Python 3.9 ve üstü gerekir.
|
|
37
|
+
|
|
38
|
+
> **Lisans uyarısı.** Bu paket MIT lisanslıdır, ancak **indirdiğiniz verilerin lisansı
|
|
39
|
+
> her portala ve veriyi yayımlayan kuruma aittir** (İBB Açık Veri Lisansı, İzmir BB Açık
|
|
40
|
+
> Veri Lisansı, CC BY 4.0, CC BY-NC ...). Paket size veriler üzerinde hiçbir hak
|
|
41
|
+
> vermez. Her veri setinin lisansını (`bilgi` komutu veya `Dataset.license_title`)
|
|
42
|
+
> okuyun, koşullarına uyun ve kaynak gösterin. Ticari olmayan (NC) lisanslara özellikle
|
|
43
|
+
> dikkat edin.
|
|
44
|
+
|
|
45
|
+
## Kurulum
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install tr-acikveri # yalnızca standart kütüphane
|
|
49
|
+
pip install "tr-acikveri[pandas]" # + DataFrame dönüşümü
|
|
50
|
+
pip install "tr-acikveri[excel]" # + XLSX/XLS okuma (pandas + openpyxl)
|
|
51
|
+
pip install "tr-acikveri[geo]" # + GeoDataFrame (geopandas)
|
|
52
|
+
pip install "tr-acikveri[certifi]" # + Mozilla CA paketi (bkz. "TLS sertifikaları")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Hızlı başlangıç (komut satırı)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
tr-acikveri portallar # CKAN portalları
|
|
59
|
+
tr-acikveri portallar --hepsi # CKAN olmayanlar dahil
|
|
60
|
+
tr-acikveri ara otopark -p ibb -p izmir -f csv -n 5
|
|
61
|
+
tr-acikveri bilgi ibb ispark-otopark-bilgileri
|
|
62
|
+
tr-acikveri indir konya otopark-bilgileri -f csv -o veri/
|
|
63
|
+
tr-acikveri kurumlar izmir --json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Örnek çıktı (kısaltılmış, 2026-11-09):
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
[konya] otopark-bilgileri
|
|
70
|
+
Otopark Bilgileri (CSV) · Destek Hizmetleri Dairesi Başkanlığı
|
|
71
|
+
[izmir] otopark-ucretleri
|
|
72
|
+
Otopark Ücretleri (CSV, XLSX) · İZELMAN A.Ş.
|
|
73
|
+
|
|
74
|
+
Toplam eşleşme 3 (izmir: 2; konya: 1); gösterilen 3.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Ortak seçenekler: `--onbellek KLASÖR`, `--onbellek-suresi SN`, `--onbelleksiz`,
|
|
78
|
+
`--zaman-asimi SN`, `--aralik SN` (aynı sunucuya iki istek arası, varsayılan 1 sn),
|
|
79
|
+
`--yeniden-deneme N`, `--iletisim E-POSTA` (User-Agent'a eklenir), `--json`.
|
|
80
|
+
`-p` portal anahtarı, şehir adı (`İzmir`, `istanbul`) veya herhangi bir CKAN adresi
|
|
81
|
+
olabilir. Yönlendirilen çıktı (ör. `> sonuc.json`) her zaman UTF-8 yazılır.
|
|
82
|
+
|
|
83
|
+
## Hızlı başlangıç (Python)
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from tr_acikveri import AcikVeri
|
|
87
|
+
|
|
88
|
+
av = AcikVeri(contact="ad.soyad@kurum.edu.tr") # iletişim adresi önerilir
|
|
89
|
+
|
|
90
|
+
sonuc = av.search("otopark", portals=["ibb", "izmir", "konya"], formats=["csv"], rows=5)
|
|
91
|
+
for ds in sonuc:
|
|
92
|
+
print(ds.portal, ds.name, ds.formats, ds.license_title)
|
|
93
|
+
print(sonuc.counts, sonuc.errors)
|
|
94
|
+
|
|
95
|
+
ds = av.dataset("konya", "otopark-bilgileri")
|
|
96
|
+
kaynak = ds.resources_by_format(["csv"])[0]
|
|
97
|
+
tablo = av.read_csv(kaynak) # indirir (önbellek) ve okur
|
|
98
|
+
print(tablo.encoding, tablo.delimiter, tablo.columns)
|
|
99
|
+
kapasite = tablo.numeric("bolgekapasite") # "1.250" -> 1250.0
|
|
100
|
+
|
|
101
|
+
df = av.to_dataframe(kaynak, numeric=True) # [pandas]
|
|
102
|
+
|
|
103
|
+
parklar = av.search("park", portals=["trabzon"], formats=["geojson"]).datasets[0]
|
|
104
|
+
geo_kaynak = parklar.resources_by_format(["geojson"])[0]
|
|
105
|
+
geo = av.read_geojson(geo_kaynak) # FeatureCollection dict
|
|
106
|
+
gdf = av.to_geodataframe(geo_kaynak) # [geo]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Tek portal için alt düzey istemci:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from tr_acikveri import CkanClient
|
|
113
|
+
|
|
114
|
+
ibb = CkanClient("ibb")
|
|
115
|
+
sayi, sayfa = ibb.search("bisiklet", formats=["geojson"], sort="metadata_modified desc")
|
|
116
|
+
for ds in ibb.iter_search("hava kalitesi", limit=200):
|
|
117
|
+
...
|
|
118
|
+
kayitlar = ibb.datastore_search(resource_id, limit=100, filters={"ilce": "Kadıköy"})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Portal kaydı
|
|
122
|
+
|
|
123
|
+
Her kayıt 2026-11-09 tarihinde `<adres>/api/3/action/status_show` adresine yapılan tek
|
|
124
|
+
bir salt okunur `GET` isteğiyle doğrulandı; lisans notları portalın `license_list`
|
|
125
|
+
ve `package_search` yanıtlarından alındı. Veri seti sayıları aynı tarihe aittir.
|
|
126
|
+
|
|
127
|
+
| Anahtar | Portal | Adres | Veri seti | Lisans (portalın bildirdiği) |
|
|
128
|
+
|---|---|---|---:|---|
|
|
129
|
+
| `ibb` | İstanbul BB | https://data.ibb.gov.tr | 565 | İBB Açık Veri Lisansı |
|
|
130
|
+
| `izmir` | İzmir BB | https://acikveri.bizizmir.com | 251 | İzmir BB Açık Veri Lisansı; bazıları CC BY / belirtilmemiş |
|
|
131
|
+
| `konya` | Konya BB | https://acikveri.konya.bel.tr | 233 | CC BY 4.0 |
|
|
132
|
+
| `gaziantep` | Gaziantep | https://acikveri.gaziantep.bel.tr | 252 | Gaziantep Açık Veri Lisansı |
|
|
133
|
+
| `balikesir` | Balıkesir BB | https://acikveri.balikesir.bel.tr | 252 | Balıkesir Açık Veri Lisansı |
|
|
134
|
+
| `denizli` | Denizli | https://acikveri.denizli.bel.tr | 39 | Denizli Açık Veri Lisansı |
|
|
135
|
+
| `trabzon` | Trabzon BB | https://acikveri.trabzon.bel.tr | 206 | Trabzon Açık Veri Lisansı |
|
|
136
|
+
| `manisa` | Manisa BB | https://acikveri.manisa.bel.tr | 1389 | Manisa BB Açık Veri Lisansı (mbb-odl-1.0) |
|
|
137
|
+
| `canakkale` | Çanakkale | https://acikveri.canakkale.bel.tr | 123 | Çanakkale Açık Veri Lisansı |
|
|
138
|
+
| `bursa-yesil` | Bursa Açık Yeşil | https://acikyesil.bursa.bel.tr | 49 | kurum lisansı (yalnızca yeşil alan verisi) |
|
|
139
|
+
| `kadikoy` | Kadıköy (ilçe) | https://acikveri.kadikoy.bel.tr | 161 | karışık: CC BY, CC BY-NC, CC BY-ND |
|
|
140
|
+
| `tuzla` | Tuzla (ilçe) | https://veri.tuzla.bel.tr | 91 | CC BY |
|
|
141
|
+
| `nilufer` | Nilüfer (ilçe) | https://acikveri.nilufer.bel.tr | 65 | çoğunda belirtilmemiş; bazıları CC BY / CC BY-NC |
|
|
142
|
+
|
|
143
|
+
Desteklenmeyen (CKAN API'si yok veya kontrol sırasında erişilemedi) ve
|
|
144
|
+
`portallar --hepsi` ile listelenenler: Ankara (seffaf.ankara.bel.tr), Kocaeli
|
|
145
|
+
(veri.kocaeli.bel.tr), Kayseri, Küçükçekmece, Sağlık Bakanlığı (özel yazılım);
|
|
146
|
+
Antalya, Sakarya ve ULASAV (ulasav.csb.gov.tr; erişilemedi, API türü doğrulanamadı).
|
|
147
|
+
Gaziantep, Denizli, Trabzon, Çanakkale, Balıkesir ve Bursa Açık Yeşil portalları
|
|
148
|
+
`ulasav-license` kimlikli ortak CKAN şablonunu kullanır; lisans metni her portalın
|
|
149
|
+
`/license` sayfasındadır.
|
|
150
|
+
|
|
151
|
+
Kayıtta olmayan bir CKAN portalı adresle kullanılabilir veya kaydedilebilir:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from tr_acikveri import Portal, register_portal, CkanClient
|
|
155
|
+
|
|
156
|
+
CkanClient("https://acikveri.ornek.bel.tr").search("imar")
|
|
157
|
+
register_portal(Portal("ornek", "Örnek Belediyesi", "https://acikveri.ornek.bel.tr",
|
|
158
|
+
city="Örnek", license_note="CC BY 4.0"))
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Portallar değişir: adres taşınabilir, API kapanabilir. Kayıttaki bilgiler kontrol
|
|
162
|
+
tarihindeki durumu yansıtır.
|
|
163
|
+
|
|
164
|
+
## API özeti
|
|
165
|
+
|
|
166
|
+
| Nesne | Açıklama |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `AcikVeri(portals=None, cache_dir=None, cache_ttl=86400, contact=None, timeout=30, min_interval=1.0, retries=3, max_workers=4)` | Çok portallı istemci |
|
|
169
|
+
| `.search(query, portals, formats, rows, organization, tags, sort)` → `SearchResult` | `datasets`, `counts`, `errors`, `total` |
|
|
170
|
+
| `.dataset(portal, ad)` → `Dataset`; `.resources(portal, ad, formats)` → `[Resource]` | Meta veri ve kaynaklar |
|
|
171
|
+
| `.organizations(portal)`, `.tags(portal, query)` | Kurumlar, etiketler |
|
|
172
|
+
| `.download(resource, dest=None, overwrite, resume, max_bytes, progress)` → `Path` | Önbelleğe veya hedefe indirme; `.meta.json` kaynak bilgisi |
|
|
173
|
+
| `.download_dataset(portal, ad, formats, dest_dir)` | Veri setinin tüm dosyaları |
|
|
174
|
+
| `.read_csv`, `.read_geojson`, `.load`, `.to_dataframe`, `.to_geodataframe` | Okuma |
|
|
175
|
+
| `CkanClient(portal)` | `search`, `iter_search`, `dataset`, `resource`, `organizations`, `tags`, `licenses`, `datastore_search`, `action` |
|
|
176
|
+
| `list_portals`, `get_portal`, `register_portal`, `Portal` | Portal kaydı |
|
|
177
|
+
| `read_csv`, `CsvTable`, `detect_encoding`, `sniff_delimiter`, `parse_number`, `read_geojson`, `geojson_crs` | Dosya okuyucular |
|
|
178
|
+
| `HttpClient`, `RetryPolicy`, `RateLimiter`, `Cache` | Taşıma katmanı |
|
|
179
|
+
| `AcikVeriError` → `HttpError`, `TransportError`, `CkanError` → `NotFoundError`, `UnsupportedPortalError`, `PortalNotFoundError`, `FormatError`, `MissingDependencyError` | Hatalar |
|
|
180
|
+
|
|
181
|
+
## Yöntem ve kaynaklar
|
|
182
|
+
|
|
183
|
+
- **CKAN Action API v3** — yalnızca okuma eylemleri (`status_show`, `package_search`,
|
|
184
|
+
`package_show`, `resource_show`, `organization_list`, `tag_list`, `license_list`,
|
|
185
|
+
`datastore_search`), hepsi `GET` ile. Kaynak: CKAN API belgeleri,
|
|
186
|
+
https://docs.ckan.org/en/2.9/api/. `package_search` için `rows` en fazla 1000'e
|
|
187
|
+
sınırlanır (CKAN'ın `ckan.search.rows_max` varsayılanı).
|
|
188
|
+
- **Biçim filtresi** — `res_format` Solr'da birebir eşleşen bir alan olduğundan,
|
|
189
|
+
portallarda görülen yazımların tamamı (`CSV`, `csv`, `.csv`, `GeoJSON`, `.shp`,
|
|
190
|
+
`Excel` ...) sunucuya gönderilir; sonuç ayrıca istemci tarafında normalleştirilmiş
|
|
191
|
+
biçimle süzülür.
|
|
192
|
+
- **HTTP** — `Retry-After` (saniye veya HTTP tarihi) ve `Range`/`Content-Range`
|
|
193
|
+
ile sürdürme: RFC 9110 §10.2.3 ve §14. Yeniden deneme 408/425/429/5xx ve ağ
|
|
194
|
+
hatalarında, üstel bekleme (+%10 rastgele) ile yapılır. Hız sınırı sunucu (host)
|
|
195
|
+
başınadır ve iş parçacıkları arasında paylaşılır.
|
|
196
|
+
- **Kodlama** — sıra: UTF-8 BOM → UTF-16 BOM → katı UTF-8 → Windows-1254 (cp1254,
|
|
197
|
+
Türkçe Windows kod sayfası) → ISO-8859-9. Ayraç, ilk 50 satırda en tutarlı sütun
|
|
198
|
+
sayısını veren adaydır (`;`, `,`, sekme, `|`; eşitlikte `;`).
|
|
199
|
+
- **Sayılar** — `parse_number` Türkçe yazımı (ondalık virgül, binlik nokta) varsayar;
|
|
200
|
+
yalnızca nokta içeren ve binlik gruplamaya uymayan değerler (`12.5`) ondalık
|
|
201
|
+
okunur. `%`, `TL`, `₺` ve boşluklar yok sayılır.
|
|
202
|
+
- **GeoJSON** — RFC 7946 (WGS 84, `EPSG:4326`). 2008 GeoJSON belirtimindeki `crs`
|
|
203
|
+
alanı varsa (`urn:ogc:def:crs:EPSG::5254` gibi) `geojson_crs` bu kodu döndürür ve
|
|
204
|
+
`to_geodataframe` onu kullanır.
|
|
205
|
+
|
|
206
|
+
## TLS sertifikaları
|
|
207
|
+
|
|
208
|
+
Sertifika doğrulaması her zaman açıktır. Bazı portallar (kontrol tarihinde
|
|
209
|
+
`data.ibb.gov.tr`) Windows'un yalnızca gerektiğinde indirdiği bir kök sertifikaya
|
|
210
|
+
zincirlenir; Python bu durumda `CERTIFICATE_VERIFY_FAILED` hatası verir.
|
|
211
|
+
`certifi` kuruluysa (`pip install "tr-acikveri[certifi]"`) paket otomatik olarak
|
|
212
|
+
Mozilla CA paketini kullanır. Alternatifler: `SSL_CERT_FILE` ortam değişkeni,
|
|
213
|
+
`HttpClient(ca_file=...)` veya `HttpClient(ssl_context=...)`.
|
|
214
|
+
|
|
215
|
+
## Önbellek
|
|
216
|
+
|
|
217
|
+
Varsayılan klasör `TR_ACIKVERI_CACHE` ortam değişkeni, yoksa Windows'ta
|
|
218
|
+
`%LOCALAPPDATA%\tr-acikveri`, diğer sistemlerde `~/.cache/tr-acikveri`'dir.
|
|
219
|
+
API yanıtları `api/` altında (varsayılan 1 gün), indirilen dosyalar
|
|
220
|
+
`files/<portal>/<kaynak kimliği>/` altında tutulur. Her dosyanın yanında kaynak
|
|
221
|
+
adresi, portal, veri seti, indirme zamanı ve HTTP doğrulayıcılarını içeren bir
|
|
222
|
+
`.meta.json` bulunur. İndirilen verileri bir git deposuna eklemeyin.
|
|
223
|
+
|
|
224
|
+
## Sınırlamalar
|
|
225
|
+
|
|
226
|
+
- Yalnızca CKAN portalları desteklenir; özel yazılımlı portallar (Ankara, Kocaeli,
|
|
227
|
+
Kayseri, Sağlık Bakanlığı ...) kayıtta yalnızca bilgi amaçlıdır.
|
|
228
|
+
- Portal listesi, veri seti sayıları ve lisans notları 2026-11-09 tarihli kontrollere
|
|
229
|
+
dayanır; değişebilir. Bağlayıcı olan, veri setinin portaldaki lisansıdır.
|
|
230
|
+
- Kodlama tespiti sezgiseldir: UTF-8 olarak geçerli olan cp1254 dosyaları (çok nadir)
|
|
231
|
+
UTF-8 sayılır; gerekirse `encoding="cp1254"` verin.
|
|
232
|
+
- `API`/`HTML` türündeki kaynaklar dosya değildir ve varsayılan olarak indirilmez.
|
|
233
|
+
- Çok portallı aramada `rows` portal başına uygulanır; sonuçlar portallar arasında
|
|
234
|
+
yeniden sıralanmaz.
|
|
235
|
+
- Önbellekteki dosya, sunucuda güncellense bile `overwrite=True` (CLI: `--yeniden`)
|
|
236
|
+
verilmedikçe yeniden indirilmez.
|
|
237
|
+
|
|
238
|
+
## Geliştirme
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
pip install -e ".[dev,pandas]"
|
|
242
|
+
pytest --cov=tr_acikveri
|
|
243
|
+
ruff check . && ruff format --check src tests && mypy src
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Testler gerçek ağa hiç çıkmaz: `tests/mockserver.py` iki CKAN portalını, hatalı
|
|
247
|
+
portalları (500, HTML), 429/503 yanıtlarını, bağlantısı yarıda kopan indirmeleri ve
|
|
248
|
+
`Range` desteği olmayan sunucuları taklit eden yerel bir HTTP sunucusudur.
|
|
249
|
+
|
|
250
|
+
## Lisans
|
|
251
|
+
|
|
252
|
+
MIT © 2026 Yusuf Eminoğlu. Bkz. [LICENSE](LICENSE). Bu lisans yalnızca yazılımı
|
|
253
|
+
kapsar; portallardan alınan veriler kendi lisanslarına tabidir.
|
|
254
|
+
|
|
255
|
+
## Academic citation
|
|
256
|
+
|
|
257
|
+
```bibtex
|
|
258
|
+
@software{eminoglu_tr_acikveri,
|
|
259
|
+
author = {Eminoğlu, Yusuf},
|
|
260
|
+
title = {tr-acikveri},
|
|
261
|
+
year = {2026},
|
|
262
|
+
version = {0.1.0},
|
|
263
|
+
url = {https://github.com/YusufEminoglu/tr_acikveri_sdk}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Ayrıca bkz. `CITATION.cff`.
|